From ddb1decf73a2573c43f5d0a2dafc88755dad1515 Mon Sep 17 00:00:00 2001 From: xbw Date: Fri, 10 Aug 2012 14:27:55 +0800 Subject: [PATCH] add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8 --- .../mach-rk30/include/mach/mtk_wcn_cmb_stub.h | 213 + drivers/mtk_wcn_combo/Kconfig | 141 + drivers/mtk_wcn_combo/Makefile | 60 + drivers/mtk_wcn_combo/common/Makefile | 92 + .../mtk_wcn_combo/common/include/core_exp.h | 253 + .../common/include/mtk_wcn_cmb_hw.h | 165 + drivers/mtk_wcn_combo/common/include/osal.h | 429 + .../mtk_wcn_combo/common/include/stp_exp.h | 303 + drivers/mtk_wcn_combo/common/include/wmt.h | 8 + .../mtk_wcn_combo/common/include/wmt_exp.h | 320 + .../mtk_wcn_combo/common/include/wmt_plat.h | 260 + drivers/mtk_wcn_combo/common/linux/hif_sdio.c | 2357 ++++ .../common/linux/hw_chrdev_test.c | 611 + .../common/linux/hw_sdio_client.c | 233 + .../common/linux/include/hif_sdio.h | 350 + .../common/linux/include/hw_test.h | 146 + .../common/linux/include/mtk_wcn_cmb_stub.h | 213 + .../common/linux/include/osal_linux.h | 120 + .../common/linux/include/osal_typedef.h | 98 + .../common/linux/include/wmt_dev.h | 50 + drivers/mtk_wcn_combo/common/linux/osal.c | 1567 +++ .../common/linux/stp_chrdev_bt.c | 527 + .../common/linux/stp_chrdev_gps.c | 442 + drivers/mtk_wcn_combo/common/linux/stp_exp.c | 304 + drivers/mtk_wcn_combo/common/linux/stp_uart.c | 1250 ++ .../common/linux/wmt_chrdev_wifi.c | 209 + drivers/mtk_wcn_combo/common/linux/wmt_dev.c | 906 ++ drivers/mtk_wcn_combo/common/linux/wmt_exp.c | 384 + .../platform/rockchip/mtk_wcn_cmb_hw_6620.c | 346 + .../rockchip/mtk_wcn_cmb_stub_rockchip.c | 348 + .../platform/rockchip/wmt_plat_rockchip.c | 906 ++ drivers/mtk_wcn_combo/drv_bt/Makefile | 43 + .../mtk_wcn_combo/drv_bt/include/hci_stp.h | 204 + drivers/mtk_wcn_combo/drv_bt/linux/hci_stp.c | 1708 +++ drivers/mtk_wcn_combo/drv_fm/Makefile | 47 + drivers/mtk_wcn_combo/drv_fm/include/fm.h | 520 + drivers/mtk_wcn_combo/drv_fm/private/Makefile | 51 + drivers/mtk_wcn_combo/drv_fm/private/mtk_fm.h | 116 + drivers/mtk_wcn_combo/drv_fm/public/Makefile | 47 + .../mtk_wcn_combo/drv_fm/public/mt6620_fm.c | 5257 ++++++++ .../mtk_wcn_combo/drv_fm/public/mt6620_fm.h | 597 + .../drv_fm/public/mt6620_fm_lib.c | 1486 +++ .../drv_fm/public/mt6620_fm_lib.h | 94 + .../drv_fm/public/mt6620_fm_reg.h | 65 + .../mtk_wcn_combo/drv_fm/public/mt6620_rds.c | 1878 +++ drivers/mtk_wcn_combo/drv_wlan/Makefile | 49 + drivers/mtk_wcn_combo/drv_wlan/p2p/Makefile | 120 + .../drv_wlan/p2p/common/wlan_p2p.c | 1867 +++ .../drv_wlan/p2p/include/mgmt/p2p_assoc.h | 104 + .../drv_wlan/p2p/include/mgmt/p2p_bss.h | 105 + .../drv_wlan/p2p/include/mgmt/p2p_fsm.h | 2664 ++++ .../drv_wlan/p2p/include/mgmt/p2p_func.h | 284 + .../drv_wlan/p2p/include/mgmt/p2p_ie.h | 28 + .../drv_wlan/p2p/include/mgmt/p2p_rlm.h | 149 + .../drv_wlan/p2p/include/mgmt/p2p_rlm_obss.h | 133 + .../drv_wlan/p2p/include/mgmt/p2p_scan.h | 167 + .../drv_wlan/p2p/include/mgmt/p2p_state.h | 88 + .../drv_wlan/p2p/include/nic/p2p.h | 235 + .../drv_wlan/p2p/include/nic/p2p_cmd_buf.h | 137 + .../drv_wlan/p2p/include/nic/p2p_mac.h | 263 + .../drv_wlan/p2p/include/nic/p2p_nic.h | 114 + .../p2p/include/nic/p2p_nic_cmd_event.h | 113 + .../drv_wlan/p2p/include/p2p_precomp.h | 265 + .../drv_wlan/p2p/include/wlan_p2p.h | 454 + .../drv_wlan/p2p/mgmt/p2p_assoc.c | 139 + .../mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_bss.c | 125 + .../mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_fsm.c | 3155 +++++ .../drv_wlan/p2p/mgmt/p2p_func.c | 2940 +++++ .../mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_ie.c | 73 + .../mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm.c | 1048 ++ .../drv_wlan/p2p/mgmt/p2p_rlm_obss.c | 414 + .../drv_wlan/p2p/mgmt/p2p_scan.c | 865 ++ .../drv_wlan/p2p/mgmt/p2p_state.c | 544 + .../mtk_wcn_combo/drv_wlan/p2p/nic/p2p_nic.c | 243 + .../drv_wlan/p2p/os/linux/gl_p2p.c | 5405 ++++++++ .../drv_wlan/p2p/os/linux/gl_p2p_cfg80211.c | 1755 +++ .../drv_wlan/p2p/os/linux/gl_p2p_init.c | 709 ++ .../drv_wlan/p2p/os/linux/gl_p2p_kal.c | 1509 +++ .../p2p/os/linux/include/gl_p2p_ioctl.h | 1085 ++ .../p2p/os/linux/include/gl_p2p_kal.h | 421 + .../drv_wlan/p2p/os/linux/include/gl_p2p_os.h | 206 + drivers/mtk_wcn_combo/drv_wlan/wlan/Makefile | 154 + .../mtk_wcn_combo/drv_wlan/wlan/common/dump.c | 583 + .../drv_wlan/wlan/common/wlan_bow.c | 3962 ++++++ .../drv_wlan/wlan/common/wlan_lib.c | 4934 ++++++++ .../drv_wlan/wlan/common/wlan_oid.c | 10556 ++++++++++++++++ .../drv_wlan/wlan/include/CFG_Wifi_File.h | 284 + .../drv_wlan/wlan/include/config.h | 1410 +++ .../drv_wlan/wlan/include/debug.h | 566 + .../drv_wlan/wlan/include/link.h | 458 + .../drv_wlan/wlan/include/mgmt/aa_fsm.h | 295 + .../drv_wlan/wlan/include/mgmt/ais_fsm.h | 719 ++ .../drv_wlan/wlan/include/mgmt/assoc.h | 191 + .../drv_wlan/wlan/include/mgmt/auth.h | 219 + .../drv_wlan/wlan/include/mgmt/bow_fsm.h | 234 + .../drv_wlan/wlan/include/mgmt/bss.h | 457 + .../drv_wlan/wlan/include/mgmt/cnm.h | 362 + .../drv_wlan/wlan/include/mgmt/cnm_mem.h | 1196 ++ .../drv_wlan/wlan/include/mgmt/cnm_scan.h | 250 + .../drv_wlan/wlan/include/mgmt/cnm_timer.h | 318 + .../drv_wlan/wlan/include/mgmt/hem_mbox.h | 486 + .../drv_wlan/wlan/include/mgmt/mib.h | 201 + .../drv_wlan/wlan/include/mgmt/privacy.h | 332 + .../drv_wlan/wlan/include/mgmt/rate.h | 155 + .../drv_wlan/wlan/include/mgmt/rlm.h | 498 + .../drv_wlan/wlan/include/mgmt/rlm_domain.h | 395 + .../drv_wlan/wlan/include/mgmt/rlm_obss.h | 208 + .../wlan/include/mgmt/rlm_protection.h | 170 + .../drv_wlan/wlan/include/mgmt/roaming_fsm.h | 245 + .../drv_wlan/wlan/include/mgmt/rsn.h | 424 + .../drv_wlan/wlan/include/mgmt/scan.h | 896 ++ .../drv_wlan/wlan/include/mgmt/sec_fsm.h | 328 + .../drv_wlan/wlan/include/mgmt/swcr.h | 220 + .../drv_wlan/wlan/include/mgmt/wapi.h | 164 + .../drv_wlan/wlan/include/mgmt/wlan_typedef.h | 128 + .../drv_wlan/wlan/include/nic/adapter.h | 1447 +++ .../drv_wlan/wlan/include/nic/bow.h | 366 + .../drv_wlan/wlan/include/nic/cmd_buf.h | 220 + .../drv_wlan/wlan/include/nic/hal.h | 654 + .../drv_wlan/wlan/include/nic/hif_emu.h | 308 + .../drv_wlan/wlan/include/nic/hif_rx.h | 271 + .../drv_wlan/wlan/include/nic/hif_tx.h | 269 + .../drv_wlan/wlan/include/nic/mac.h | 2178 ++++ .../drv_wlan/wlan/include/nic/mt5931_reg.h | 340 + .../drv_wlan/wlan/include/nic/mt6620_reg.h | 330 + .../drv_wlan/wlan/include/nic/nic.h | 764 ++ .../drv_wlan/wlan/include/nic/nic_rx.h | 577 + .../drv_wlan/wlan/include/nic/nic_tx.h | 679 + .../drv_wlan/wlan/include/nic/que_mgt.h | 1185 ++ .../drv_wlan/wlan/include/nic/wlan_def.h | 1056 ++ .../drv_wlan/wlan/include/nic_cmd_event.h | 1824 +++ .../wlan/include/nic_init_cmd_event.h | 225 + .../drv_wlan/wlan/include/p2p_typedef.h | 310 + .../drv_wlan/wlan/include/precomp.h | 385 + .../drv_wlan/wlan/include/pwr_mgt.h | 191 + .../drv_wlan/wlan/include/queue.h | 233 + .../drv_wlan/wlan/include/rftest.h | 361 + .../drv_wlan/wlan/include/typedef.h | 281 + .../drv_wlan/wlan/include/wlan_bow.h | 591 + .../drv_wlan/wlan/include/wlan_lib.h | 987 ++ .../drv_wlan/wlan/include/wlan_oid.h | 2058 +++ .../drv_wlan/wlan/mgmt/aaa_fsm.c | 1552 +++ .../drv_wlan/wlan/mgmt/ais_fsm.c | 4582 +++++++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/assoc.c | 2087 +++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/auth.c | 1398 ++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/bss.c | 3103 +++++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm.c | 814 ++ .../drv_wlan/wlan/mgmt/cnm_mem.c | 1339 ++ .../drv_wlan/wlan/mgmt/cnm_timer.c | 575 + .../drv_wlan/wlan/mgmt/hem_mbox.c | 844 ++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/mib.c | 146 + .../drv_wlan/wlan/mgmt/privacy.c | 1069 ++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/rate.c | 591 + .../mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm.c | 1788 +++ .../drv_wlan/wlan/mgmt/rlm_domain.c | 713 ++ .../drv_wlan/wlan/mgmt/rlm_obss.c | 502 + .../drv_wlan/wlan/mgmt/rlm_protection.c | 152 + .../drv_wlan/wlan/mgmt/roaming_fsm.c | 625 + .../mtk_wcn_combo/drv_wlan/wlan/mgmt/rsn.c | 2653 ++++ .../drv_wlan/wlan/mgmt/saa_fsm.c | 2056 +++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/scan.c | 3002 +++++ .../drv_wlan/wlan/mgmt/scan_fsm.c | 1159 ++ .../drv_wlan/wlan/mgmt/sec_fsm.c | 1306 ++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/swcr.c | 1213 ++ .../mtk_wcn_combo/drv_wlan/wlan/mgmt/wapi.c | 568 + .../mtk_wcn_combo/drv_wlan/wlan/nic/cmd_buf.c | 262 + drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic.c | 4370 +++++++ .../drv_wlan/wlan/nic/nic_cmd_event.c | 1588 +++ .../drv_wlan/wlan/nic/nic_pwr_mgt.c | 825 ++ .../mtk_wcn_combo/drv_wlan/wlan/nic/nic_rx.c | 3568 ++++++ .../mtk_wcn_combo/drv_wlan/wlan/nic/nic_tx.c | 2020 +++ .../mtk_wcn_combo/drv_wlan/wlan/nic/que_mgt.c | 4786 +++++++ .../drv_wlan/wlan/os/linux/gl_bow.c | 1459 +++ .../drv_wlan/wlan/os/linux/gl_init.c | 2810 ++++ .../drv_wlan/wlan/os/linux/gl_kal.c | 3660 ++++++ .../drv_wlan/wlan/os/linux/gl_proc.c | 855 ++ .../drv_wlan/wlan/os/linux/gl_rst.c | 517 + .../drv_wlan/wlan/os/linux/gl_wext.c | 4548 +++++++ .../drv_wlan/wlan/os/linux/gl_wext_priv.c | 2292 ++++ .../drv_wlan/wlan/os/linux/hif/sdio/arm.c | 68 + .../wlan/os/linux/hif/sdio/include/hif.h | 269 + .../wlan/os/linux/hif/sdio/include/hif_sdio.h | 311 + .../os/linux/hif/sdio/include/mtk_porting.h | 53 + .../drv_wlan/wlan/os/linux/hif/sdio/sdio.S | 0 .../drv_wlan/wlan/os/linux/hif/sdio/sdio.c | 1281 ++ .../drv_wlan/wlan/os/linux/hif/sdio/x86.c | 68 + .../drv_wlan/wlan/os/linux/include/gl_kal.h | 1988 +++ .../drv_wlan/wlan/os/linux/include/gl_os.h | 1093 ++ .../drv_wlan/wlan/os/linux/include/gl_rst.h | 171 + .../drv_wlan/wlan/os/linux/include/gl_sec.h | 64 + .../wlan/os/linux/include/gl_typedef.h | 320 + .../drv_wlan/wlan/os/linux/include/gl_wext.h | 413 + .../wlan/os/linux/include/gl_wext_priv.h | 439 + .../drv_wlan/wlan/os/linux/platform.c | 694 + .../mtk_wcn_combo/drv_wlan/wlan/os/version.h | 197 + drivers/mtk_wcn_combo/gps/Makefile | 49 + drivers/mtk_wcn_combo/gps/gps.c | 1117 ++ include/linux/gps.h | 25 + 198 files changed, 179804 insertions(+) create mode 100755 arch/arm/mach-rk30/include/mach/mtk_wcn_cmb_stub.h create mode 100755 drivers/mtk_wcn_combo/Kconfig create mode 100755 drivers/mtk_wcn_combo/Makefile create mode 100755 drivers/mtk_wcn_combo/common/Makefile create mode 100755 drivers/mtk_wcn_combo/common/include/core_exp.h create mode 100755 drivers/mtk_wcn_combo/common/include/mtk_wcn_cmb_hw.h create mode 100755 drivers/mtk_wcn_combo/common/include/osal.h create mode 100755 drivers/mtk_wcn_combo/common/include/stp_exp.h create mode 100755 drivers/mtk_wcn_combo/common/include/wmt.h create mode 100755 drivers/mtk_wcn_combo/common/include/wmt_exp.h create mode 100755 drivers/mtk_wcn_combo/common/include/wmt_plat.h create mode 100755 drivers/mtk_wcn_combo/common/linux/hif_sdio.c create mode 100755 drivers/mtk_wcn_combo/common/linux/hw_chrdev_test.c create mode 100755 drivers/mtk_wcn_combo/common/linux/hw_sdio_client.c create mode 100755 drivers/mtk_wcn_combo/common/linux/include/hif_sdio.h create mode 100755 drivers/mtk_wcn_combo/common/linux/include/hw_test.h create mode 100755 drivers/mtk_wcn_combo/common/linux/include/mtk_wcn_cmb_stub.h create mode 100755 drivers/mtk_wcn_combo/common/linux/include/osal_linux.h create mode 100755 drivers/mtk_wcn_combo/common/linux/include/osal_typedef.h create mode 100755 drivers/mtk_wcn_combo/common/linux/include/wmt_dev.h create mode 100755 drivers/mtk_wcn_combo/common/linux/osal.c create mode 100755 drivers/mtk_wcn_combo/common/linux/stp_chrdev_bt.c create mode 100755 drivers/mtk_wcn_combo/common/linux/stp_chrdev_gps.c create mode 100755 drivers/mtk_wcn_combo/common/linux/stp_exp.c create mode 100755 drivers/mtk_wcn_combo/common/linux/stp_uart.c create mode 100755 drivers/mtk_wcn_combo/common/linux/wmt_chrdev_wifi.c create mode 100755 drivers/mtk_wcn_combo/common/linux/wmt_dev.c create mode 100755 drivers/mtk_wcn_combo/common/linux/wmt_exp.c create mode 100755 drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_hw_6620.c create mode 100755 drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_stub_rockchip.c create mode 100755 drivers/mtk_wcn_combo/common/platform/rockchip/wmt_plat_rockchip.c create mode 100755 drivers/mtk_wcn_combo/drv_bt/Makefile create mode 100755 drivers/mtk_wcn_combo/drv_bt/include/hci_stp.h create mode 100755 drivers/mtk_wcn_combo/drv_bt/linux/hci_stp.c create mode 100755 drivers/mtk_wcn_combo/drv_fm/Makefile create mode 100755 drivers/mtk_wcn_combo/drv_fm/include/fm.h create mode 100755 drivers/mtk_wcn_combo/drv_fm/private/Makefile create mode 100755 drivers/mtk_wcn_combo/drv_fm/private/mtk_fm.h create mode 100755 drivers/mtk_wcn_combo/drv_fm/public/Makefile create mode 100755 drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.c create mode 100755 drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.h create mode 100755 drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.c create mode 100755 drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.h create mode 100755 drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_reg.h create mode 100755 drivers/mtk_wcn_combo/drv_fm/public/mt6620_rds.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/Makefile create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/Makefile create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/common/wlan_p2p.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_assoc.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_bss.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_fsm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_func.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_ie.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm_obss.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_scan.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_state.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_cmd_buf.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_mac.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic_cmd_event.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/p2p_precomp.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/include/wlan_p2p.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_assoc.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_bss.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_fsm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_func.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_ie.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm_obss.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_scan.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_state.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/nic/p2p_nic.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_cfg80211.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_init.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_kal.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_ioctl.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_kal.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_os.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/Makefile create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/common/dump.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_bow.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_lib.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_oid.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/CFG_Wifi_File.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/config.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/debug.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/link.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/aa_fsm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/ais_fsm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/assoc.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/auth.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bow_fsm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bss.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_mem.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_scan.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_timer.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/hem_mbox.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/mib.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/privacy.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rate.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_domain.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_obss.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_protection.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/roaming_fsm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rsn.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/scan.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/sec_fsm.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/swcr.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wapi.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wlan_typedef.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/adapter.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/bow.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/cmd_buf.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hal.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_emu.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_rx.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_tx.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mac.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt5931_reg.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt6620_reg.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_rx.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_tx.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/que_mgt.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/wlan_def.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic_cmd_event.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic_init_cmd_event.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/p2p_typedef.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/precomp.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/pwr_mgt.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/queue.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/rftest.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/typedef.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_bow.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_lib.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_oid.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/aaa_fsm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/ais_fsm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/assoc.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/auth.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/bss.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_mem.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_timer.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/hem_mbox.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/mib.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/privacy.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rate.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_domain.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_obss.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_protection.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/roaming_fsm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rsn.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/saa_fsm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan_fsm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/sec_fsm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/swcr.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/wapi.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/nic/cmd_buf.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_cmd_event.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_pwr_mgt.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_rx.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_tx.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/nic/que_mgt.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_bow.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_init.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_kal.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_proc.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_rst.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext_priv.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/arm.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif_sdio.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/mtk_porting.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/sdio.S create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/sdio.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/x86.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_kal.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_os.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_rst.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_sec.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_typedef.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext_priv.h create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/platform.c create mode 100755 drivers/mtk_wcn_combo/drv_wlan/wlan/os/version.h create mode 100755 drivers/mtk_wcn_combo/gps/Makefile create mode 100755 drivers/mtk_wcn_combo/gps/gps.c create mode 100755 include/linux/gps.h diff --git a/arch/arm/mach-rk30/include/mach/mtk_wcn_cmb_stub.h b/arch/arm/mach-rk30/include/mach/mtk_wcn_cmb_stub.h new file mode 100755 index 000000000000..18682c0d69ec --- /dev/null +++ b/arch/arm/mach-rk30/include/mach/mtk_wcn_cmb_stub.h @@ -0,0 +1,213 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _MTK_WCN_CMB_STUB_H_ +#define _MTK_WCN_CMB_STUB_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 { + 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_MAX = 4, +} 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; + +#if 1 /* copied from mt_combo.h */ +typedef enum { + COMBO_AUDIO_STATE_0 = 0, /* 0000: BT_PCM_OFF & FM analog (line in/out) */ + COMBO_AUDIO_STATE_1 = 1, /* 0001: BT_PCM_ON & FM analog (in/out) */ + COMBO_AUDIO_STATE_2 = 2, /* 0010: BT_PCM_OFF & FM digital (I2S) */ + COMBO_AUDIO_STATE_3 = 3, /* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */ + COMBO_AUDIO_STATE_MAX = 4, +} COMBO_AUDIO_STATE; + +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_MAX, +} COMBO_IF; +#endif + +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 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; +} 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 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); + +#if 0 /* remove obsolete audio_ctrl APIs. Use stub_aif_ctrl()! */ +/* [GeorgeKuo] Stub functions for other kernel built-in modules to call. + * Keep them unchanged temporarily. Move mt_combo functions to mtk_wcn_combo. + */ +extern int mtk_wcn_cmb_stub_audio_ctrl_ex(COMBO_AUDIO_STATE state, u32 clt_ctrl); +static inline int mtk_wcn_cmb_stub_audio_ctrl(COMBO_AUDIO_STATE state) { + return mtk_wcn_cmb_stub_audio_ctrl_ex(state, 1); +} +#endif + +/* 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 mt_combo_plt_enter_deep_idle(COMBO_IF src); +extern int mt_combo_plt_exit_deep_idle(COMBO_IF src); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_WCN_CMB_STUB_H_ */ + diff --git a/drivers/mtk_wcn_combo/Kconfig b/drivers/mtk_wcn_combo/Kconfig new file mode 100755 index 000000000000..c63cd2ce6687 --- /dev/null +++ b/drivers/mtk_wcn_combo/Kconfig @@ -0,0 +1,141 @@ +menu "MediaTek Connectivity Combo Chip Config" + +config MTK_COMBO + bool "MediaTek Connectivity Combo Chip Support" + help + MTK connectivity combo chip driver for MT6620 + +# +# MTK Combo Chip Selection +# +choice + prompt "Select Chip" + depends on MTK_COMBO + +config MTK_COMBO_CHIP_MT6620 + bool "MT6620" + +#config MTK_COMBO_CHIP_MT6628 +# bool "MT6628" +endchoice + +# +# 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_BT_HW_TEST + tristate "MediaTek Combo Chip BT Hardware Test driver" + depends on MTK_COMBO + help + MTK BT /dev/stpbt driver for autobt hardware test tool (mtk_stp_bt.ko) + +config MTK_COMBO_BT_HCI + tristate "MediaTek Combo Chip BlueZ driver" + depends on BT && MTK_COMBO + help + MTK BT driver for BlueZ (hci_stp.ko) + +config MTK_COMBO_FM + tristate "MediaTek Combo Chip FM driver" + depends on MTK_COMBO + help + MTK FM /dev/fm driver (mt6620_fm_drv.ko, mtk_fm_priv.ko) + +config MTK_COMBO_WIFI + tristate "MediaTek Combo Chip Wi-Fi support" + depends on MTK_COMBO + depends on MMC + depends on IPV6 + select WIRELESS_EXT + select WEXT_PRIV + help + This module adds support for wireless adapters based on + MTK MT6620 chipset. + + This driver uses the kernel's wireless extensions subsystem. + + If you choose to build a module, it'll be called dhd. Say M if + unsure. + +#config MTK_COMBO_WIFI_FW_PATH +# depends on MTK_COMBO_WIFI +# string "Firmware path" +# default "/system/etc/firmware/WIFI_RAM_CODE" +# help +# Path to the firmware file + +config MTK_COMBO_WIFI_DEBUG + depends on MTK_COMBO_WIFI + bool "Enable debug output from MT6620 driver" + help + Enable debug messages output from MT6620 driver + +config MTK_COMBO_WIFI_PROC + depends on MTK_COMBO_WIFI + bool "Enable procfs support" + help + Enable procfs support. + +#config MTK_WAPI_SUPPORT +# depends on MTK_COMBO_WIFI +# bool "Enable WAPI support in MT6620 driver" +# help +# Enable WAPI support for devices using MT6620 + +choice + prompt "Host Interface" + depends on MTK_COMBO_WIFI + +config MTK_COMBO_WIFI_HIF_SDIO1 + bool "SDIO #1" + depends on MTK_COMBO_WIFI +endchoice + + +config MTK_GPS + tristate "MediaTek GPS Support" + help + MTK GPS /dev/gps driver (mtk_gps.ko) + +config MTK_COMBO_GPS + tristate "MediaTek Combo Chip GPS driver" + depends on MTK_COMBO && MTK_GPS + help + MTK GPS /dev/stpgps driver (mtk_stp_gps.ko) + +endmenu diff --git a/drivers/mtk_wcn_combo/Makefile b/drivers/mtk_wcn_combo/Makefile new file mode 100755 index 000000000000..7d1689039149 --- /dev/null +++ b/drivers/mtk_wcn_combo/Makefile @@ -0,0 +1,60 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# combo driver: MT6620 +# 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 + #subdir-ccflags-y += -I$(src)/common/include -I$(src)/common/linux/include + #used for binary release script + #KERNEL_PATH := $(pwd) + #OBJ_PATH := $(pwd) + obj-$(CONFIG_MTK_COMBO) += common/ + obj-$(CONFIG_MTK_COMBO_FM) += drv_fm/ + obj-$(CONFIG_MTK_COMBO_WIFI) += drv_wlan/ + + #Use BT HCI driver + obj-$(CONFIG_MTK_COMBO_BT_HCI) += drv_bt/ + obj-$(CONFIG_MTK_GPS) += gps/ + +# 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/mtk_wcn_combo/common/Makefile b/drivers/mtk_wcn_combo/common/Makefile new file mode 100755 index 000000000000..32608e8a605c --- /dev/null +++ b/drivers/mtk_wcn_combo/common/Makefile @@ -0,0 +1,92 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + +#always := $(shell tar -zxf $(src)/core.tar.gz -C $(src)) +always := $(shell if [ -f $(src)/core.tar.gz ]; then tar -zxf $(src)/core.tar.gz -C $(src); fi) +#always := $(shell tar -zxf $(src)/linux/pri.tar.gz -C $(src)/linux) +#always := $(shell if [ -f $(src)/linux/pri.tar.gz ]; then tar -zxf $(src)/linux/pri.tar.gz -C $(src)/linux; fi) + +ccflags-y += -I$(src)/include -I$(src)/linux/include -I$(src)/core/include + +# WMT DRIVER +obj-$(CONFIG_MTK_COMBO_COMM) += mtk_stp_wmt.o +# WMT DRIVER-core part +mtk_stp_wmt-y := core/wmt_core.o core/wmt_ctrl.o core/wmt_conf.o +mtk_stp_wmt-y += core/wmt_dbg.o core/wmt_func.o core/wmt_lib.o +mtk_stp_wmt-y += core/btm_core.o +mtk_stp_wmt-y += core/psm_core.o # to be removed +mtk_stp_wmt-y += core/stp_core.o core/stp_dbg.o +mtk_stp_wmt-$(CONFIG_MTK_COMBO_CHIP_MT6620) += core/wmt_ic_6620.o +#mtk_stp_wmt-$(CONFIG_MTK_COMBO_CHIP_MT6628) += core/wmt_ic_6628.o + +# WMT DRIVER-linux part +mtk_stp_wmt-y += linux/wmt_dev.o linux/wmt_exp.o linux/stp_exp.o +# WMT DRIVER-OSAL +mtk_stp_wmt-y += linux/osal.o + +# WMT DRIVER-platform part, specified by string CONFIG_MTK_COMBO_PLAT_PATH +PLAT := $(shell echo $(CONFIG_MTK_COMBO_PLAT_PATH)) +mtk_stp_wmt-y += platform/$(PLAT)/wmt_plat_$(PLAT).o +# WMT DRIVER-platform chip part. Select desired hw according to project configuration +mtk_stp_wmt-$(CONFIG_MTK_COMBO_CHIP_MT6620) += platform/$(PLAT)/mtk_wcn_cmb_hw_6620.o +mtk_stp_wmt-$(CONFIG_MTK_COMBO_CHIP_MT6628) += platform/$(PLAT)/mtk_wcn_cmb_hw_6628.o + +# WMT stub part (built-in kernel image) +obj-y += platform/$(PLAT)/mtk_wcn_cmb_stub_$(PLAT).o + +# HIF-SDIO DRIVER +obj-$(CONFIG_MTK_COMBO_COMM) += mtk_hif_sdio.o +mtk_hif_sdio-y := linux/hif_sdio.o + +# STP-UART DRIVER +obj-$(CONFIG_MTK_COMBO_COMM_UART) += mtk_stp_uart.o +mtk_stp_uart-y := linux/stp_uart.o + +# STP-SDIO DRIVER +#obj-$(CONFIG_MTK_COMBO_COMM_SDIO) += mtk_stp_sdio.o +#mtk_stp_sdio-y := linux/pri/stp_sdio.o + +# MTK BT HW TEST DRIVER +obj-$(CONFIG_MTK_COMBO_BT_HW_TEST) += mtk_stp_bt.o +mtk_stp_bt-y := linux/stp_chrdev_bt.o + +# STP-GPS DIVER +obj-$(CONFIG_MTK_COMBO_GPS) += mtk_stp_gps.o +mtk_stp_gps-y := linux/stp_chrdev_gps.o + +# WMT-WIFI DIVER +obj-$(CONFIG_MTK_COMBO_WIFI) += mtk_wmt_wifi.o +mtk_wmt_wifi-y := linux/wmt_chrdev_wifi.o + + diff --git a/drivers/mtk_wcn_combo/common/include/core_exp.h b/drivers/mtk_wcn_combo/common/include/core_exp.h new file mode 100755 index 000000000000..1b6c711e5d46 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/include/core_exp.h @@ -0,0 +1,253 @@ + +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _CORE_EXP_H_ +#define _CORE_EXP_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define CFG_WMT_DBG_SUPPORT (1) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal.h" +#include "wmt_exp.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define MAX_WIFI_ON_TIME (5500) // in ms? +#define WMT_LIB_RX_TIMEOUT (2000) // in ms? + +#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) + +#define OP_FUNCTION_ACTIVE (0) + + +#define STATUS_OP_INVALID (0) +#define STATUS_FUNCTION_INVALID (1) + +#define STATUS_FUNCTION_ACTIVE (31) +#define STATUS_FUNCTION_INACTIVE (32) + +#define defaultPatchName "mt66xx_patch_hdr.bin" +#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) + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +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_SDIO_CTRL = 18, + WMT_OPID_MAX +} ENUM_WMT_OPID_T, *P_ENUM_WMT_OPID_T; + +typedef enum _ENUM_WMT_UART_FC_T +{ + WMT_UART_NO_FC = 0, + WMT_UART_MTK_SW_FC = 1, + WMT_UART_LUX_SW_FC = 2, + WMT_UART_HW_FC = 3, + WMT_UART_MAX +} ENUM_WMT_UART_FC_T, *P_ENUM_UART_FC_T; + + +typedef OSAL_OP_DAT WMT_OP; +typedef P_OSAL_OP_DAT P_WMT_OP; + + +typedef INT32 (*IF_TX)(const UINT8 *data, const UINT32 size, UINT32 *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 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 struct _WMT_HIF_CONF { + UINT32 hifType; // HIF Type + UINT32 uartFcCtrl; // UART FC config + UINT32 au4HifConf[DWCNT_HIF_CONF]; // HIF Config + UINT32 au4StrapConf[DWCNT_STRAP_CONF]; // Strap Config +} WMT_HIF_CONF, *P_WMT_HIF_CONF; + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +extern INT32 wmt_lib_init(VOID); +extern INT32 wmt_lib_deinit(VOID); +extern P_OSAL_OP wmt_lib_get_free_op (VOID); +extern MTK_WCN_BOOL wmt_lib_put_act_op (P_OSAL_OP pOp); +extern INT32 wmt_lib_host_awake_get(VOID); +extern INT32 wmt_lib_host_awake_put(VOID); +extern VOID wmt_lib_disable_psm_monitor(VOID); +extern VOID wmt_lib_enable_psm_monitor(VOID); +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_msgcb_reg (ENUM_WMTDRV_TYPE_T eType,PF_WMT_CB pCb); + +extern INT32 wmt_lib_msgcb_unreg (ENUM_WMTDRV_TYPE_T eType); + +extern VOID wmt_lib_ps_set_sdio_psop (PF_WMT_SDIO_PSOP own_cb); +extern ENUM_WMTHWVER_TYPE_T wmt_lib_get_hwver (VOID); +extern VOID wmt_lib_flush_rx(VOID); +extern INT32 wmt_lib_trigger_cmd_signal (INT32 result); +extern UCHAR *wmt_lib_get_cmd(VOID); +extern P_OSAL_EVENT wmt_lib_get_cmd_event(VOID); +extern MTK_WCN_BOOL wmt_lib_get_cmd_status(VOID); +extern INT32 wmt_lib_set_patch_name(UCHAR *cPatchName); + +extern INT32 wmt_lib_set_hif(ULONG hifconf); +extern P_WMT_HIF_CONF wmt_lib_get_hif(VOID); + + +extern INT32 stp_drv_init(VOID); +extern VOID stp_drv_exit(VOID); +extern INT32 mtk_wcn_stp_init(const mtkstp_callback * const cb_func); +extern INT32 mtk_wcn_stp_deinit(VOID); +extern VOID mtk_wcn_stp_flush_rx_queue(UINT32 type); +extern INT32 mtk_wcn_stp_send_data_raw(const UINT8 *buffer, const UINT32 length, const UINT8 type); + + +extern INT32 wmt_dbg_proc_read(CHAR *page, CHAR **start, LONG off, INT32 count, INT32 *eof, VOID *data); +extern INT32 wmt_dbg_proc_write(CHAR *buffer); + + +#endif + diff --git a/drivers/mtk_wcn_combo/common/include/mtk_wcn_cmb_hw.h b/drivers/mtk_wcn_combo/common/include/mtk_wcn_cmb_hw.h new file mode 100755 index 000000000000..4b6aadd3b5f7 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/include/mtk_wcn_cmb_hw.h @@ -0,0 +1,165 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _MTK_WCN_CMB_HW_H_ +#define _MTK_WCN_CMB_HW_H_ + +#include "osal_typedef.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 struct _PWR_SEQ_TIME_ +{ + UINT32 rtcStableTime; + UINT32 ldoStableTime; + UINT32 rstStableTime; + UINT32 offStableTime; + UINT32 onStableTime; +}PWR_SEQ_TIME, *P_PWR_SEQ_TIME; + + +/******************************************************************************* +* 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 +******************************************************************************** +*/ + +extern INT32 mtk_wcn_cmb_hw_pwr_off (VOID); +extern INT32 mtk_wcn_cmb_hw_pwr_on (VOID); +extern INT32 mtk_wcn_cmb_hw_rst (VOID); +extern INT32 mtk_wcn_cmb_hw_init (P_PWR_SEQ_TIME pPwrSeqTime); +extern INT32 mtk_wcn_cmb_hw_deinit (VOID); + + +#endif /* _MTK_WCN_CMB_HW_H_ */ + diff --git a/drivers/mtk_wcn_combo/common/include/osal.h b/drivers/mtk_wcn_combo/common/include/osal.h new file mode 100755 index 000000000000..9913ecea7ed6 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/include/osal.h @@ -0,0 +1,429 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _OSAL_H_ +#define _OSAL_H_ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define OS_BIT_OPS_SUPPORT (1) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "osal_typedef.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define MAX_THREAD_NAME_LEN (16) +#define MAX_WAKE_LOCK_NAME_LEN (16) +#define OSAL_OP_BUF_SIZE (64) +#define OSAL_OP_DATA_SIZE (32) +#define DBG_LOG_STR_SIZE (512) + +#define OSAL_NAME_MAX (256) + + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + +#define osal_sizeof(x) sizeof(x) +#define osal_array_size(x) sizeof(x)/sizeof(x[0]) + + +#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) \ + { \ + (prb)->read = (prb)->write = 0; \ + (prb)->size = (qsize); \ + } + +#define RB_PUT(prb, value) \ +{ \ + if (!RB_FULL( prb )) { \ + (prb)->queue[ (prb)->write & RB_MASK(prb) ] = value; \ + ++((prb)->write); \ + } \ + else { \ + osal_assert(!RB_FULL(prb)); \ + } \ +} + +#define RB_GET(prb, value) \ +{ \ + 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)); \ + } \ +} + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef VOID (*P_TIMEOUT_HANDLER)(ULONG); +typedef INT32 (*P_COND)(VOID *); + +typedef struct _OSAL_TIMER_ +{ + TIMER_REF pTimer; + P_TIMEOUT_HANDLER timeoutHandler; + ULONG timeroutHandlerData; +}OSAL_TIMER, *P_OSAL_TIMER; + +typedef struct _OSAL_UNSLEEPABLE_LOCK_ +{ + SPINLOCK_REF pLock; + ULONG flag; +}OSAL_UNSLEEPABLE_LOCK, *P_OSAL_UNSLEEPABLE_LOCK; + +typedef struct _OSAL_SLEEPABLE_LOCK_ +{ + MUTEX_REF pLock; +}OSAL_SLEEPABLE_LOCK, *P_OSAL_SLEEPABLE_LOCK; + + +typedef struct _OSAL_SIGNAL_ +{ + COMPLETION_REF pComp; + UINT32 timeoutValue; +}OSAL_SIGNAL, *P_OSAL_SIGNAL; + + +typedef struct _OSAL_EVENT_ +{ + WAITQUEUE_REF pWaitQueue; + UINT32 timeoutValue; + INT32 waitFlag; + +}OSAL_EVENT, *P_OSAL_EVENT; + +typedef struct _OSAL_THREAD_ +{ + THREAD_REF 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_REF 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 _OSAL_FIRMWARE_ +{ + UINT32 size; + const UINT8 *data; +}OSAL_FIRMWARE,*P_OSAL_FIRMWARE; + +typedef struct _OSAL_OP_DAT { + UINT32 opId; // Event ID + UINT32 u4InfoBit; // Reserved + UINT32 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_ +{ + WAKELOCK_REF pWakeLock; + UINT8 name[MAX_WAKE_LOCK_NAME_LEN]; +} OSAL_WAKE_LOCK, *P_OSAL_WAKE_LOCK; + +typedef enum{ + OSAL_RETURN_OK = 0, + OSAL_RETIRN_BAD_ADDRESS = -14, +}OSAL_RETURN_ERR; + +typedef struct _OSAL_BIT_OP_VAR_ +{ + ULONG data; + OSAL_UNSLEEPABLE_LOCK opLock; +}OSAL_BIT_OP_VAR, *P_OSAL_BIT_OP_VAR; + +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 LONG osal_strtol(const char *str, char **c, UINT32 adecimal); +extern INT32 osal_snprintf(char *buf, UINT32 len, const char*fmt, ...); + +extern INT32 osal_print(const char *str, ...); +extern INT32 osal_dbg_print(const char *str, ...); +extern INT32 osal_err_print(const char *str, ...); +extern INT32 osal_info_print(const char *str, ...); +extern INT32 osal_warn_print(const char *str, ...); +extern INT32 osal_loud_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_vfree(const VOID *dst); +extern VOID osal_kfree(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 VOID * osal_kzalloc_sleep(UINT32 size); +extern VOID* osal_kzalloc_unsleep(UINT32 size); + +extern INT32 osal_msleep(UINT32 ms); + +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_deinit(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_unsleepable_lock_init (P_OSAL_UNSLEEPABLE_LOCK ); +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 ); + +extern INT32 osal_sleepable_lock_init (P_OSAL_SLEEPABLE_LOCK ); +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); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#define osal_assert(condition) if (!(condition)) {osal_err_print("%s, %d, (%s)\n", __FILE__, __LINE__, #condition);} + +#endif /* _OSAL_H_ */ + diff --git a/drivers/mtk_wcn_combo/common/include/stp_exp.h b/drivers/mtk_wcn_combo/common/include/stp_exp.h new file mode 100755 index 000000000000..6bad140302f1 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/include/stp_exp.h @@ -0,0 +1,303 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _STP_EXP_H_ +#define _STP_EXP_H_ + +#include "osal_typedef.h" +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#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 MTKSTP_MAX_TASK_NUM (7) + +#define MTKSTP_BUFFER_SIZE (16384) //Size of RX Queue + + + +/******************************************************************************* +* 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 (*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, + STP_MAX_IF_TX +}ENUM_STP_TX_IF_TYPE; + +/******************************************************************************* +* 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 +******************************************************************************** +*/ + +/***************************************************************************** +* 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 UINT8 *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 INT32 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 +******************************************************************************** +*/ + +#endif /* _WMT_EXP_H_ */ + + + + + + + + + + + + + diff --git a/drivers/mtk_wcn_combo/common/include/wmt.h b/drivers/mtk_wcn_combo/common/include/wmt.h new file mode 100755 index 000000000000..f4931871f339 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/include/wmt.h @@ -0,0 +1,8 @@ + +#ifndef _MTKWMT_H_ +#define _MTKWMT_H_ +#include "wmt_core.h" + + + +#endif /*_MTKWMT_H_*/ diff --git a/drivers/mtk_wcn_combo/common/include/wmt_exp.h b/drivers/mtk_wcn_combo/common/include/wmt_exp.h new file mode 100755 index 000000000000..c68bb10646d0 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/include/wmt_exp.h @@ -0,0 +1,320 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _WMT_EXP_H_ +#define _WMT_EXP_H_ + +#include +#include "osal.h" + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#if 0 +/* moved from wmt_lib.h */ +#ifdef CONFIG_MTK_COMBO_COMM_PS +/* Enable common i/f power saving handling support */ +/* FixMe SDIO power saving is to be integrated */ +#define CFG_WMT_PS_SUPPORT 1 +#else +#define CFG_WMT_PS_SUPPORT 0 +#endif +#endif + +#define CFG_WMT_PS_SUPPORT 1 + +/******************************************************************************* +* 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...) if (gWmtDbgLvl >= WMT_LOG_LOUD) { osal_loud_print(DFT_TAG "[L]%s:" fmt, __FUNCTION__ ,##arg);} +#define WMT_DBG_FUNC(fmt, arg...) if (gWmtDbgLvl >= WMT_LOG_DBG) { osal_dbg_print(DFT_TAG "[D]%s:" fmt, __FUNCTION__ ,##arg);} +#define WMT_INFO_FUNC(fmt, arg...) if (gWmtDbgLvl >= WMT_LOG_INFO) { osal_info_print(DFT_TAG "[I]%s:" fmt, __FUNCTION__ ,##arg);} +#define WMT_WARN_FUNC(fmt, arg...) if (gWmtDbgLvl >= WMT_LOG_WARN) { osal_warn_print(DFT_TAG "[W]%s:" fmt, __FUNCTION__ ,##arg);} +#define WMT_ERR_FUNC(fmt, arg...) if (gWmtDbgLvl >= WMT_LOG_ERR) { osal_err_print(DFT_TAG "[E]%s(%d):" fmt, __FUNCTION__ , __LINE__, ##arg);} +#define WMT_TRC_FUNC(f) if (gWmtDbgLvl >= WMT_LOG_DBG) { osal_dbg_print(DFT_TAG "<%s> <%d>\n", __FUNCTION__, __LINE__);} +#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 + +/******************************************************************************* +* 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 + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +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; + +// 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_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_E7 = 0x6, + WMTHWVER_MT6620_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_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 enum _ENUM_WMTRSTMSG_TYPE_T{ + WMTRSTMSG_RESET_START = 0x0, + WMTRSTMSG_RESET_END = 0x1, + 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. */ + UINT32 /* Buffer size in unit of byte */ +); + +typedef enum _SDIO_PS_OP{ + OWN_SET = 0, + OWN_CLR = 1 +} SDIO_PS_OP; + + +typedef INT32 (*PF_WMT_SDIO_PSOP)(SDIO_PS_OP); + +#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 + +/******************************************************************************* +* 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 +******************************************************************************** +*/ +/*subsystem function ctrl APIs*/ +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 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 + ); + +/* +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); + +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); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _WMT_EXP_H_ */ + + + + + + + diff --git a/drivers/mtk_wcn_combo/common/include/wmt_plat.h b/drivers/mtk_wcn_combo/common/include/wmt_plat.h new file mode 100755 index 000000000000..1972b53ce149 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/include/wmt_plat.h @@ -0,0 +1,260 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _WMT_PLAT_H_ +#define _WMT_PLAT_H_ +#include "osal_typedef.h" +#include "osal.h" +#include +#include "mtk_wcn_cmb_hw.h" + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#if 0 /* [GeorgeKuo] remove COMBO_AUDIO FLAG */ +#define COMBO_AUDIO_BT_MASK (0x1UL) +#define COMBO_AUDIO_BT_PCM_ON (0x1UL << 0) +#define COMBO_AUDIO_BT_PCM_OFF (0x0UL << 0) + +#define COMBO_AUDIO_FM_MASK (0x2UL) +#define COMBO_AUDIO_FM_LINEIN (0x0UL << 1) +#define COMBO_AUDIO_FM_I2S (0x1UL << 1) + +#define COMBO_AUDIO_PIN_MASK (0x4UL) +#define COMBO_AUDIO_PIN_SHARE (0x1UL << 2) +#define COMBO_AUDIO_PIN_SEPARATE (0x0UL << 2) +#endif + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +typedef enum _ENUM_FUNC_STATE_{ + FUNC_OFF = 0, + FUNC_ON = 1, + FUNC_RST = 2, + FUNC_CTRL_MAX, +} ENUM_FUNC_STATE, *P_ENUM_FUNC_STATE; + +typedef enum _ENUM_PIN_ID_{ + PIN_LDO = 0, + PIN_PMU = 1, + PIN_RTC = 2, + PIN_RST = 3, + PIN_BGF_EINT = 4, + PIN_WIFI_EINT = 5, + PIN_ALL_EINT = 6, + PIN_UART_GRP = 7, + PIN_PCM_GRP = 8, + PIN_I2S_GRP = 9, + PIN_SDIO_GRP = 10, + PIN_GPS_SYNC = 11, + PIN_GPS_LNA = 12, + 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_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; + + +/******************************************************************************* +* 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 +******************************************************************************** +*/ + + +/******************************************************************************* +* 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 (P_PWR_SEQ_TIME pPwrSeqTime); + +INT32 +wmt_plat_deinit (VOID); + +#if 0 +INT32 +wmt_plat_irq_ctrl ( + ENUM_FUNC_STATE state + ); +#endif + +INT32 +wmt_plat_pwr_ctrl ( + ENUM_FUNC_STATE state + ); + +INT32 +wmt_plat_ps_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_audio_ctrl ( + CMB_STUB_AIF_X state, + CMB_STUB_AIF_CTRL ctrl + ); + +INT32 +wmt_plat_sdio_ctrl ( + UINT32 sdioPortNum, + ENUM_FUNC_STATE on + ); + + +INT32 +wmt_plat_wake_lock_ctrl( + ENUM_WL_OP opId + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _WMT_PLAT_H_ */ + diff --git a/drivers/mtk_wcn_combo/common/linux/hif_sdio.c b/drivers/mtk_wcn_combo/common/linux/hif_sdio.c new file mode 100755 index 000000000000..a49ffea8f00c --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/hif_sdio.c @@ -0,0 +1,2357 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* +** $Id: $ +*/ + +/*! \file "hif_sdio.c" + * \brief + * + * detailed description +*/ + +/* +** $Log: $ + * + * 07 25 2010 george.kuo + * + * Move hif_sdio driver to linux directory. + * + * 07 23 2010 george.kuo + * + * Add MT6620 driver source tree + * , including char device driver (wmt, bt, gps), stp driver, interface driver (tty ldisc and hif_sdio), and bt hci driver. +** +** +*/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define HIF_SDIO_UPDATE (1) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "hif_sdio.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +//#define DRV_NAME "[hif_sdio]" + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +/*! + * \brief A macro used to generate hif_sdio client's context + * + * Generate a context for hif_sdio client based on the following input parameters + * |<-card id (16bits)->|<-block size in unit of 256 bytes(8 bits)->|<-function number(4bits)->|<-index(4bits)->| + * + * \param manf the 16 bit manufacturer id + * \param card the 16 bit card id + * \param func the 16 bit function number + * \param b_sz the 16 bit function block size + */ +#define CLTCTX(cid, func, blk_sz, idx) \ + (MTK_WCN_HIF_SDIO_CLTCTX)( (((UINT32)(cid) & 0xFFFFUL) << 16) | \ + (((UINT32)(func) & 0xFUL) << 4) | \ + (((UINT32)(blk_sz) & 0xFF00UL) << 0) | \ + (((UINT32)idx & 0xFUL) << 0) ) + +/*! + * \brief A set of macros used to get information out of an hif_sdio client context + * + * Generate a context for hif_sdio client based on the following input parameters + */ +#define CLTCTX_CID(ctx) (((ctx) >> 16) & 0xFFFF) +#define CLTCTX_FUNC(ctx) (((ctx) >> 4) & 0xF) +#define CLTCTX_BLK_SZ(ctx) (((ctx) >> 0) & 0xFF00) +#define CLTCTX_IDX(ctx) ((ctx) & 0xF) +#define CLTCTX_IDX_VALID(idx) ((idx >= 0) && (idx < CFG_CLIENT_COUNT)) + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static int hif_sdio_probe ( + struct sdio_func *func, + const struct sdio_device_id *id + ); + +static void hif_sdio_remove ( + struct sdio_func *func + ); + +static void hif_sdio_irq ( + struct sdio_func *func + ); + +static int hif_sdio_clt_probe_func ( + MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p, + INT8 probe_idx + ); + +static void hif_sdio_clt_probe_worker( + struct work_struct *work + ); + +static int hif_sdio_find_probed_list_index_by_func( + struct sdio_func *func + ); + +static int hif_sdio_find_probed_list_index_by_id_func( + UINT16 vendor, + UINT16 device, + UINT16 func_num + ); + +static void hif_sdio_init_clt_list( + INT32 index + ); + +static int hif_sdio_find_clt_list_index ( + UINT16 vendor, + UINT16 device, + UINT16 func_num + ); + +static int hif_sdio_check_supported_sdio_id( + UINT16 vendor, + UINT16 device + ); + +static int hif_sdio_check_duplicate_sdio_id( + UINT16 vendor, + UINT16 device, + UINT16 func_num + ); + +static int hif_sdio_add_clt_list( + INT32* clt_index_p, + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo, + UINT32 tbl_index + ); + +static INT32 hif_sdio_stp_on( + void + ); + +static INT32 hif_sdio_stp_off( + void + ); + +static INT32 hif_sdio_wifi_on( + void + ); + +static INT32 hif_sdio_wifi_off( + void + ); + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/* 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) }, + { /* end: all zeroes */ }, +}; + +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 = hif_sdio_probe, + .remove = hif_sdio_remove, +}; + +/* Registered client driver list */ +/* static list g_hif_sdio_clt_drv_list */ +static MTK_WCN_HIF_SDIO_REGISTINFO g_hif_sdio_clt_drv_list[CFG_CLIENT_COUNT]; + +/* MMC probed function list */ +/* static list g_hif_sdio_probed_func_list */ +static MTK_WCN_HIF_SDIO_PROBEINFO g_hif_sdio_probed_func_list[CFG_CLIENT_COUNT]; + +/* spin lock info for g_hif_sdio_clt_drv_list and g_hif_sdio_probed_func_list */ +static MTK_WCN_HIF_SDIO_LOCKINFO g_hif_sdio_lock_info; + +/* reference count, debug information? */ +static int gRefCount; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("MediaTek Inc WCN_SE_CS3"); +MODULE_DESCRIPTION("MediaTek MT6620 HIF SDIO Driver"); + +MODULE_DEVICE_TABLE(sdio, mtk_sdio_id_tbl); + +UINT32 gHifSdioDbgLvl = HIF_SDIO_LOG_ERR;//HIF_SDIO_LOG_INFO; Modify loglevel + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +/*! + * \brief Translate CLTCTX into a pointer to struct sdio_func if it is valid + * + * Translate a CLTCTX into a pointer to struct sdio_func if it is + * 1) probed by mmc_core, and + * 2) client driver is registered, and + * 3) clt_idx of client driver is valid + * + * \param ctx a context provided by client driver + * + * \retval null if any condition is not valie + * \retval a pointer to a struct sdio_func mapped by provided ctx + */ +static inline struct sdio_func* hif_sdio_ctx_to_func ( + MTK_WCN_HIF_SDIO_CLTCTX ctx) +{ + UINT32 probe_index; + + //4 <1> check if ctx is valid, registered, and probed + probe_index = CLTCTX_IDX(ctx); + if (unlikely(!CLTCTX_IDX_VALID(probe_index))) /* invalid index in CLTCTX */ + { + HIF_SDIO_WARN_FUNC("invalid ctx(0x%x)\n", ctx); + return NULL; + } + else + { + if (unlikely(g_hif_sdio_probed_func_list[probe_index].clt_idx < 0)) /* the client has not been registered */ + { + HIF_SDIO_WARN_FUNC("can't find client idx in probed list!ctx(0x%x) prob_idx(%d) clt_idx(%d)\n", + ctx, probe_index, g_hif_sdio_probed_func_list[probe_index].clt_idx); + return NULL; + } + } + return g_hif_sdio_probed_func_list[probe_index].func; +} + +/*! + * \brief MTK hif sdio client registration function + * + * Client uses this function to register itself to hif_sdio driver + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_client_reg ( + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo + ) +{ + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 clt_index = -1; + UINT32 i = 0; + UINT32 j = 0; + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; + + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <1> check input pointer is valid + HIF_SDIO_ASSERT( pinfo ); + + //4 <2> check if input parameters are all supported and valid + for ( i=0; ifunc_tbl_size; i++ ) + { + ret = hif_sdio_check_supported_sdio_id( pinfo->func_tbl[i].manf_id, pinfo->func_tbl[i].card_id ); + if(ret) + { + HIF_SDIO_WARN_FUNC("vendor id(0x%x) and device id(0x%x) of sdio_func are not supported in mtk_sdio_id_tbl!\n", + pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id); + goto out; + } + } + HIF_SDIO_DBG_FUNC("hif_sdio_check_supported_sdio_id() done!\n"); + + //4 <3> check if the specific {manf id, card id, function number} tuple is + //4 already resigstered + for ( i=0; ifunc_tbl_size; i++ ) + { + ret = hif_sdio_check_duplicate_sdio_id( pinfo->func_tbl[i].manf_id, pinfo->func_tbl[i].card_id, pinfo->func_tbl[i].func_num ); + if(ret) + { + HIF_SDIO_WARN_FUNC("vendor id(0x%x), device id(0x%x), and fun_num(%d) of sdio_func are duplicated in g_hif_sdio_clt_drv_list!\n", + pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id, + pinfo->func_tbl[i].func_num ); + goto out; + } + } + HIF_SDIO_DBG_FUNC("hif_sdio_check_duplicate_sdio_id() done!\n"); + + //4 <4> add the specified {manf id, card id, function number} tuple to registered client list + HIF_SDIO_DBG_FUNC("pinfo->func_tbl_size:%d\n", pinfo->func_tbl_size); + for ( i=0; ifunc_tbl_size; i++ ) + { + ret = hif_sdio_add_clt_list( &clt_index, pinfo, i ); + if(ret) + { + HIF_SDIO_WARN_FUNC("client's info are added in registed client list failed (buffer is full)!\n"); + goto out; + } + HIF_SDIO_DBG_FUNC("hif_sdio_add_clt_list() done (gRefCount=%d)!\n", gRefCount); + + //4 <5> if the specific {manf id, card id, function number} tuple has already + //4 been probed by mmc, schedule another task to call client's .hif_clt_probe() + for ( j=0; jmanf_id == g_hif_sdio_probed_func_list[j].func->vendor) &&\ + (g_hif_sdio_clt_drv_list[clt_index].func_info->card_id == g_hif_sdio_probed_func_list[j].func->device) &&\ + (g_hif_sdio_clt_drv_list[clt_index].func_info->func_num == g_hif_sdio_probed_func_list[j].func->num) ) + { + g_hif_sdio_probed_func_list[j].clt_idx = clt_index; + // probed spin unlock + spin_unlock_bh( &g_hif_sdio_lock_info.probed_list_lock ); + + /* use worker thread to perform the client's .hif_clt_probe() */ + clt_probe_worker_info = vmalloc( sizeof(MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO) ); + INIT_WORK( &clt_probe_worker_info->probe_work, hif_sdio_clt_probe_worker ); + clt_probe_worker_info->registinfo_p = &g_hif_sdio_clt_drv_list[clt_index]; + clt_probe_worker_info->probe_idx = j; + schedule_work( &clt_probe_worker_info->probe_work ); + + //4 <5.1> remember to do claim_irq for the func if it's irq had been released. + if ( !(g_hif_sdio_probed_func_list[j].func->irq_handler) ) + { + sdio_claim_host(g_hif_sdio_probed_func_list[j].func); + ret = sdio_claim_irq(g_hif_sdio_probed_func_list[j].func, hif_sdio_irq); + sdio_release_host(g_hif_sdio_probed_func_list[j].func); + HIF_SDIO_INFO_FUNC("sdio_claim_irq for func(0x%p) j(%d) v(0x%x) d(0x%x) ok\n", + g_hif_sdio_probed_func_list[j].func, j, + g_hif_sdio_probed_func_list[j].func->vendor, + g_hif_sdio_probed_func_list[j].func->device + ); + } + //4 <5.2> Reset the block size of the function provided by client + HIF_SDIO_INFO_FUNC("Reset sdio block size: %d!\n", g_hif_sdio_clt_drv_list[clt_index].func_info->blk_sz); + sdio_claim_host(g_hif_sdio_probed_func_list[j].func); + ret = sdio_set_block_size(g_hif_sdio_probed_func_list[j].func,\ + g_hif_sdio_clt_drv_list[clt_index].func_info->blk_sz); + sdio_release_host(g_hif_sdio_probed_func_list[j].func); + } + else + { + // probed spin unlock + spin_unlock_bh( &g_hif_sdio_lock_info.probed_list_lock ); + } + } + HIF_SDIO_DBG_FUNC("map g_hif_sdio_clt_drv_list to g_hif_sdio_probed_func_list done!\n"); + } + ret = HIF_SDIO_ERR_SUCCESS; + gRefCount++; + +out: + //4 error handling + + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_reg() */ + +/*! + * \brief MTK hif sdio client un-registration function + * + * Client uses this function to un-register itself + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_client_unreg ( + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo + ) +{ + INT32 ret = -HIF_SDIO_ERR_FAIL; + INT32 clt_list_index = 0; + UINT32 i = 0; + UINT32 j = 0; + + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <1> check if input pointer is valid + HIF_SDIO_ASSERT( pinfo ); + + //4 <2> check if input parameters are all supported and valid + for ( i=0; ifunc_tbl_size; i++ ) + { + ret = hif_sdio_check_supported_sdio_id( pinfo->func_tbl[i].manf_id, pinfo->func_tbl[i].card_id ); + if(ret) + { + HIF_SDIO_WARN_FUNC("vendor id(0x%x) and device id(0x%x) of sdio_func are not supported in mtk_sdio_id_tbl!\n", + pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id); + goto out; + } + } + + //4 <3> check if the specific {manf id, card id, function number} tuple is already resigstered + //4 and find the corresponding client ctx and call client's .hif_clt_remove() in THIS context + for ( i=0; ifunc_tbl_size; i++ ) + { + clt_list_index = hif_sdio_find_clt_list_index(pinfo->func_tbl[i].manf_id, pinfo->func_tbl[i].card_id, pinfo->func_tbl[i].func_num); + if ( clt_list_index < 0 ) + { + HIF_SDIO_WARN_FUNC("vendor id(0x%x), device id(0x%x), and fun_num(%d) client info is not in the client's registed list!\n", + pinfo->func_tbl[i].manf_id, + pinfo->func_tbl[i].card_id, + pinfo->func_tbl[i].func_num ); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + + //4 <4> mark the specified {manf id, card id, function number} tuple as + //4 un-registered and invalidate client's context + hif_sdio_init_clt_list( clt_list_index ); + + /* un-map g_hif_sdio_clt_drv_list index in g_hif_sdio_probed_func_list */ + for ( j=0; j check if ctx is valid, registered, and probed +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if( probe_index < 0 ) /* the function has not been probed */ + { + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + else + { + if ( g_hif_sdio_probed_func_list[probe_index].clt_idx < 0 ) /* the client has not been registered */ + { + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + + //4 <2> + sdio_claim_host(func); + *pvb = sdio_readb(func, offset, &ret); + sdio_release_host(func); + + //4 <3> check result code and return proper error code + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_writeb ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + UINT8 vb + ) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func* func; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + int probe_index = -1; + struct sdio_func* func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + + //4 <1> check if ctx is valid, registered, and probed +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if( probe_index < 0 ) /* the function has not been probed */ + { + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + else + { + if ( g_hif_sdio_probed_func_list[probe_index].clt_idx < 0 ) /* the client has not been registered */ + { + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + + //4 <1.1> check if input parameters are valid + + //4 <2> + sdio_claim_host(func); + sdio_writeb(func, vb, offset, &ret); + sdio_release_host(func); + + //4 <3> check result code and return proper error code + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_readl ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pvl + ) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func* func; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + int probe_index = -1; + struct sdio_func* func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT( pvl ); + + //4 <1> check if ctx is valid, registered, and probed +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if( probe_index < 0 ) /* the function has not been probed */ + { + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + else + { + if ( g_hif_sdio_probed_func_list[probe_index].clt_idx < 0 ) /* the client has not been registered */ + { + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + //4 <1.1> check if input parameters are valid + + //4 <2> + sdio_claim_host(func); + *pvl = sdio_readl(func, offset, &ret); + sdio_release_host(func); + + //4 <3> check result code and return proper error code + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_writel ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + UINT32 vl + ) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func* func; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + int probe_index = -1; + struct sdio_func* func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + + //4 <1> check if ctx is valid, registered, and probed +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if( probe_index < 0 ) /* the function has not been probed */ + { + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + else + { + if ( g_hif_sdio_probed_func_list[probe_index].clt_idx < 0 ) /* the client has not been registered */ + { + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + //4 <1.1> check if input parameters are valid + + //4 <2> + sdio_claim_host(func); + sdio_writel(func, vl, offset, &ret); + sdio_release_host(func); + + //4 <3> check result code and return proper error code + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_client_unreg() */ + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_read_buf ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pbuf, + UINT32 len + ) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func* func; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + int probe_index = -1; + struct sdio_func* func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT( pbuf ); + + //4 <1> check if ctx is valid, registered, and probed +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if( probe_index < 0 ) /* the function has not been probed */ + { + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + else + { + if ( g_hif_sdio_probed_func_list[probe_index].clt_idx < 0 ) /* the client has not been registered */ + { + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + //4 <1.1> check if input parameters are valid + + //4 <2> + sdio_claim_host(func); + ret = sdio_readsb(func, pbuf, offset, len); + sdio_release_host(func); + + //4 <3> check result code and return proper error code + +out: + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} /* end of mtk_wcn_hif_sdio_read_buf() */ + + +/*! + * \brief + * + * detailed descriptions + * + * \param ctx client's context variable + * + * \retval 0 register successfully + * \retval < 0 list error code here + */ +INT32 mtk_wcn_hif_sdio_write_buf ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pbuf, + UINT32 len + ) +{ +#if HIF_SDIO_UPDATE + INT32 ret; + struct sdio_func* func; +#else + INT32 ret = -HIF_SDIO_ERR_FAIL; + int probe_index = -1; + struct sdio_func* func = 0; +#endif + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT( pbuf ); + + //4 <1> check if ctx is valid, registered, and probed +#if HIF_SDIO_UPDATE + ret = -HIF_SDIO_ERR_FAIL; + func = hif_sdio_ctx_to_func(ctx); + if (!func) { + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } +#else + probe_index = CLTCTX_IDX(ctx); + if( probe_index < 0 ) /* the function has not been probed */ + { + HIF_SDIO_WARN_FUNC("can't find client in probed list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + else + { + if ( g_hif_sdio_probed_func_list[probe_index].clt_idx < 0 ) /* the client has not been registered */ + { + HIF_SDIO_WARN_FUNC("can't find client in registered list!\n"); + ret = -HIF_SDIO_ERR_FAIL; + goto out; + } + } + func = g_hif_sdio_probed_func_list[probe_index].func; +#endif + //4 <1.1> check if input parameters are valid + + //4 <2> + sdio_claim_host(func); + ret = sdio_writesb(func, offset, pbuf, len); + sdio_release_host(func); + + //4 <3> check result code and return proper error code + +out: + HIF_SDIO_DBG_FUNC("ret(%d) end!\n", ret); + + return ret; +} /* end of mtk_wcn_hif_sdio_write_buf() */ + +/*! + * \brief store client driver's private data function. + * + * + * \param clent's MTK_WCN_HIF_SDIO_CLTCTX. + * + * \retval none. + */ +void mtk_wcn_hif_sdio_set_drvdata( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + void* private_data_p + ) +{ + UINT8 probed_idx = CLTCTX_IDX(ctx); + + if (unlikely(!CLTCTX_IDX_VALID(probed_idx))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid idx in ctx(0x%x), private_data_p not stored!\n", ctx); + } + else { + /* store client driver's private data to dev driver */ + g_hif_sdio_probed_func_list[probed_idx].private_data_p = private_data_p; + HIF_SDIO_DBG_FUNC("private_data_p(0x%p) for ctx(0x%x) probed idx(%d) stored!\n", + private_data_p, ctx, probed_idx); + } +} + +/*! + * \brief get client driver's private data function. + * + * + * \param clent's MTK_WCN_HIF_SDIO_CLTCTX. + * + * \retval private data pointer. + */ +void* mtk_wcn_hif_sdio_get_drvdata( + MTK_WCN_HIF_SDIO_CLTCTX ctx + ) +{ + UINT8 probed_idx = CLTCTX_IDX(ctx); + + /* get client driver's private data to dev driver */ + if (likely(CLTCTX_IDX_VALID(probed_idx))) + { + return g_hif_sdio_probed_func_list[probed_idx].private_data_p; + } + else + { + /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid idx in ctx(0x%x), return null!\n", ctx); + return NULL; + } +} + +/*! + * \brief control stp/wifi on/off from wmt. + * + * + * \param (1)control function type, (2)on/off control. + * + * \retval (1)control results ,(2)unknow type: -5. + * \retval 0:success, -11:not probed, -12:already on, -13:not registered, other errors. + */ +INT32 +mtk_wcn_hif_sdio_wmt_control ( + WMT_SDIO_FUNC_TYPE func_type, + MTK_WCN_BOOL is_on + ) +{ + // TODO:[FixMe][George]: return value of this function shall distinguish + // 1) not probed by mmc_core yet or + // 2) probed by mmc_core but init fail... + switch (func_type) { + case WMT_SDIO_FUNC_STP: + if (is_on == MTK_WCN_BOOL_TRUE) { + return hif_sdio_stp_on(); + } + else { + return hif_sdio_stp_off(); + } + break; + + case WMT_SDIO_FUNC_WIFI: + if (is_on == MTK_WCN_BOOL_TRUE) { + return hif_sdio_wifi_on(); + } + else { + return hif_sdio_wifi_off(); + } + break; + + default: + HIF_SDIO_WARN_FUNC("unknown type(%d)\n", func_type); + return HIF_SDIO_ERR_INVALID_PARAM; + } +} + +/*! + * \brief ??? + * + * \detail ??? + * + * \param ctx a context provided by client driver + * \param struct device ** ??? + * + * \retval none + */ +void mtk_wcn_hif_sdio_get_dev( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + struct device **dev + ) +{ +#if HIF_SDIO_UPDATE + struct sdio_func* func; +#else + UINT8 probe_index = CLTCTX_IDX(ctx); +#endif + +#if HIF_SDIO_UPDATE + *dev = NULL; //ensure we does not return any invalid value back. + func = hif_sdio_ctx_to_func(ctx); + if (unlikely(!func)) { + HIF_SDIO_WARN_FUNC("no valid *func with ctx(0x%x)\n", ctx); + return; + } + else { + *dev = &(func->dev); + HIF_SDIO_DBG_FUNC("return *dev(0x%p) for ctx(0x%x)\n", *dev, ctx); + } +#else + if (probe_index < 0) { + HIF_SDIO_WARN_FUNC("func not probed, probe_index = %d", probe_index); + return; + } + else{ + *dev = &g_hif_sdio_probed_func_list[probe_index].func->dev; + } +#endif +} + +/*! + * \brief enable irq handling for client function driver + * + * \detail ??? + * + * \param ctx a context provided by client driver + * \param struct device ** ??? + * + * \retval none + */ +void mtk_wcn_hif_sdio_enable_irq( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + MTK_WCN_BOOL enable + ) +{ + UINT8 probed_idx = CLTCTX_IDX(ctx); + + if (unlikely(!CLTCTX_IDX_VALID(probed_idx))) { /* invalid index in CLTCTX */ + HIF_SDIO_WARN_FUNC("invalid idx in ctx(0x%x), sdio_irq no change\n", ctx); + return; + } + + /* store client driver's private data to dev driver */ + g_hif_sdio_probed_func_list[probed_idx].sdio_irq_enabled = enable; + smp_wmb(); + HIF_SDIO_INFO_FUNC("ctx(0x%x) sdio irq enable(%d)\n", + ctx, (MTK_WCN_BOOL_FALSE == enable) ? 0 : 1); + +} + +/*! + * \brief client's probe() function. + * + * + * \param work queue structure. + * + * \retval none. + */ +static int hif_sdio_clt_probe_func ( + MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p, + INT8 probe_idx + ) +{ + UINT16 card_id = 0; + UINT16 func_num = 0; + UINT16 blk_sz = 0; + int ret; + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_ASSERT( registinfo_p ); + if (!registinfo_p) { + HIF_SDIO_WARN_FUNC("registinfo_p NULL!!!\n"); + return -1; + } + + /* special case handling: if the clt's unregister is called during probe procedures */ + if ( !registinfo_p->func_info || !registinfo_p->sdio_cltinfo) { + HIF_SDIO_WARN_FUNC("client's registinfo_p is cleared !!!\n"); + return -1; + } + + card_id = registinfo_p->func_info->card_id; + func_num = registinfo_p->func_info->func_num; + blk_sz = registinfo_p->func_info->blk_sz; + ret = registinfo_p->sdio_cltinfo->hif_clt_probe( CLTCTX(card_id, func_num, blk_sz, probe_idx),\ + registinfo_p->func_info ); + + HIF_SDIO_INFO_FUNC("clt_probe_func card_id(%x) func_num(%x) blk_sz(%d) prob_idx(%x) ret(%d) %s\n", + card_id, func_num, blk_sz, probe_idx, ret, (ret) ? "fail" : "ok"); + + return ret; +} + +/*! + * \brief client's probe() worker. + * + * + * \param work queue structure. + * + * \retval none. + */ +static void hif_sdio_clt_probe_worker( + struct work_struct *work + ) +{ + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_worker_info_p = 0; + UINT16 card_id = 0; + UINT16 func_num = 0; + UINT16 blk_sz = 0; + INT8 prob_idx = 0; + + HIF_SDIO_DBG_FUNC("start!\n"); + + HIF_SDIO_ASSERT( work ); + + /* get client's information */ + clt_worker_info_p = container_of( work, MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO, probe_work ); + HIF_SDIO_ASSERT( clt_worker_info_p ); + HIF_SDIO_ASSERT( clt_worker_info_p->registinfo_p ); + + /* special case handling: if the clt's unregister is called during probe procedures */ + if ( (clt_worker_info_p->registinfo_p->func_info == 0) || (clt_worker_info_p->registinfo_p->sdio_cltinfo==0) ) + { + HIF_SDIO_WARN_FUNC("client's registinfo_p is cleared !!!\n"); + vfree( clt_worker_info_p ); + return; + } + + card_id = clt_worker_info_p->registinfo_p->func_info->card_id; + func_num = clt_worker_info_p->registinfo_p->func_info->func_num; + blk_sz = clt_worker_info_p->registinfo_p->func_info->blk_sz; + prob_idx = clt_worker_info_p->probe_idx; + + /* Execute client's probe() func */ + clt_worker_info_p->registinfo_p->sdio_cltinfo->hif_clt_probe( CLTCTX(card_id, func_num, blk_sz, prob_idx),\ + clt_worker_info_p->registinfo_p->func_info ); + + vfree( clt_worker_info_p ); + + HIF_SDIO_DBG_FUNC("card_id(0x%x) func_num(0x%x) blk_sz(0x%x) prob_idx(0x%x)\n", card_id, func_num, blk_sz, prob_idx); + HIF_SDIO_DBG_FUNC("end!\n"); +} + +/*! + * \brief client's probe() worker. + * + * + * \param work queue structure. + * + * \retval none. + */ +static void +hif_sdio_dump_probe_list (void) +{ + int i; + + HIF_SDIO_DBG_FUNC("== DUMP probed list start ==\n"); + + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (g_hif_sdio_probed_func_list[i].func) { + HIF_SDIO_DBG_FUNC("index(%d) func(0x%p) clt_idx(%d)\n", + i, g_hif_sdio_probed_func_list[i].func, + g_hif_sdio_probed_func_list[i].clt_idx); + + HIF_SDIO_DBG_FUNC("vendor(0x%x) device(0x%x) num(0x%x) state(%d)\n", + g_hif_sdio_probed_func_list[i].func->vendor, + g_hif_sdio_probed_func_list[i].func->device, + g_hif_sdio_probed_func_list[i].func->num, + g_hif_sdio_probed_func_list[i].on_by_wmt); + + } + } + + HIF_SDIO_DBG_FUNC("== DUMP probed list end ==\n"); +} + + +/*! + * \brief Initialize g_hif_sdio_probed_func_list + * + * + * \param index of g_hif_sdio_probed_func_list. + * + * \retval none. + */ +static void hif_sdio_init_probed_list( + INT32 index + ) +{ + if ( (index >= 0) && (index < CFG_CLIENT_COUNT) ) + { + /* probed spin lock */ + spin_lock_bh( &g_hif_sdio_lock_info.probed_list_lock ); + g_hif_sdio_probed_func_list[index].func = 0; + g_hif_sdio_probed_func_list[index].clt_idx = -1; + g_hif_sdio_probed_func_list[index].private_data_p = 0; + g_hif_sdio_probed_func_list[index].on_by_wmt = MTK_WCN_BOOL_FALSE; + /* probed spin unlock */ + spin_unlock_bh( &g_hif_sdio_lock_info.probed_list_lock ); + } + else + { + HIF_SDIO_ERR_FUNC("index is out of g_hif_sdio_probed_func_list[] boundary!\n"); + } +} + + +/*! + * \brief Initialize g_hif_sdio_clt_drv_list + * + * + * \param index of g_hif_sdio_clt_drv_list. + * + * \retval none. + */ +static void hif_sdio_init_clt_list( + INT32 index + ) +{ + // client list spin lock + spin_lock_bh( &g_hif_sdio_lock_info.clt_list_lock ); + if ( (index >= 0) && (index < CFG_CLIENT_COUNT) ) + { + g_hif_sdio_clt_drv_list[index].sdio_cltinfo = 0; + g_hif_sdio_clt_drv_list[index].func_info = 0; + } + else + { + HIF_SDIO_ERR_FUNC("index is out of g_hif_sdio_clt_drv_list[] boundary!\n"); + } + // client list spin unlock + spin_unlock_bh( &g_hif_sdio_lock_info.clt_list_lock ); +} + + +/*! + * \brief find matched g_hif_sdio_probed_func_list index from sdio function handler + * + * + * \param sdio function handler + * + * \retval -1 index not found + * \retval >= 0 return found index + */ +static int hif_sdio_find_probed_list_index_by_func( + struct sdio_func* func + ) +{ + int i = 0; + + HIF_SDIO_ASSERT( func ); + + for( i=0; i= 0 return found index + */ +static int hif_sdio_find_probed_list_index_by_id_func( + UINT16 vendor, + UINT16 device, + UINT16 func_num + ) +{ + int i; + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (g_hif_sdio_probed_func_list[i].func) { + HIF_SDIO_DBG_FUNC("probed entry: vendor(0x%x) device(0x%x) num(0x%x)\n", + g_hif_sdio_probed_func_list[i].func->vendor, + g_hif_sdio_probed_func_list[i].func->device, + g_hif_sdio_probed_func_list[i].func->num); + } + } + for (i = 0; i < CFG_CLIENT_COUNT; i++) { + if (!g_hif_sdio_probed_func_list[i].func) { + continue; + } + else if ( (g_hif_sdio_probed_func_list[i].func->vendor == vendor) && + (g_hif_sdio_probed_func_list[i].func->device == device) && + (g_hif_sdio_probed_func_list[i].func->num == func_num) ) + { + return i; + } + } + + if (i == CFG_CLIENT_COUNT ) { + /* + printk(KERN_INFO DRV_NAME "Cannot find vendor:0x%x, device:0x%x, func_num:0x%x, i=%d\n", + vendor, device, func_num, i); + */ + /* client func has not been probed */ + return -1; + } + return -1; +} + +/*! + * \brief find matched g_hif_sdio_clt_drv_list index + * + * find the matched g_hif_sdio_clt_drv_list index from card_id and function number. + * + * \param vendor id, device id, and function number of the sdio card + * + * \retval -1 index not found + * \retval >= 0 return found index + */ +static int hif_sdio_find_clt_list_index ( + UINT16 vendor, + UINT16 device, + UINT16 func_num + ) +{ + int i = 0; + + for( i=0; imanf_id == vendor ) &&\ + (g_hif_sdio_clt_drv_list[i].func_info->card_id == device ) &&\ + (g_hif_sdio_clt_drv_list[i].func_info->func_num == func_num ) ) + { + return i; + } + } + } + + return -1; +} + + +/*! + * \brief check if the vendor, device ids are supported in mtk_sdio_id_tbl. + * + * + * \param vendor id and device id of the sdio card + * + * \retval (-HIF_SDIO_ERR_FAIL) vendor, device ids are not suppported + * \retval HIF_SDIO_ERR_SUCCESS vendor, device ids are suppported + */ +static int hif_sdio_check_supported_sdio_id( + UINT16 vendor, + UINT16 device + ) +{ + int i = 0; + + for ( i=0; imanf_id == vendor ) &&\ + ( g_hif_sdio_clt_drv_list[i].func_info->card_id == device ) &&\ + ( g_hif_sdio_clt_drv_list[i].func_info->func_num == func_num ) ) + { + return (-HIF_SDIO_ERR_DUPLICATED); /* duplicated */ + } + } + } + return HIF_SDIO_ERR_SUCCESS; /* Not duplicated */ +} + + +/*! + * \brief Add the client info into g_hif_sdio_clt_drv_list. + * + * + * \param [output] client's index pointer. + * \param MTK_WCN_HIF_SDIO_CLTINFO of client's contex. + * + * \retval (-HIF_SDIO_ERR_FAIL) Add to clt_list successfully + * \retval HIF_SDIO_ERR_SUCCESS Add to clt_list failed (buffer is full) + */ +static int hif_sdio_add_clt_list( + INT32* clt_index_p, + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo, + UINT32 tbl_index + ) +{ + int i = 0; + + HIF_SDIO_ASSERT( clt_index_p ); + HIF_SDIO_ASSERT( pinfo ); + + for( i=0; ifunc_tbl[tbl_index]); + g_hif_sdio_clt_drv_list[i].sdio_cltinfo = pinfo; + // client list spin unlock + spin_unlock_bh( &g_hif_sdio_lock_info.clt_list_lock ); + *clt_index_p = i; + return HIF_SDIO_ERR_SUCCESS; /* Add to client list successfully */ + } + // client list spin unlock + spin_unlock_bh( &g_hif_sdio_lock_info.clt_list_lock ); + } + return (-HIF_SDIO_ERR_FAIL); /* Add to client list failed (buffer is full) */ +} + + +/*! + * \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 hif_sdio_probe ( + struct sdio_func *func, + const struct sdio_device_id *id + ) +{ + int ret = 0; + int i = 0; + MTK_WCN_HIF_SDIO_PROBEINFO* hif_sdio_probed_funcp = 0; + INT32 probe_index = -1; +#if 0 + INT32 clt_index = -1; + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; +#endif + + HIF_SDIO_INFO_FUNC("start!\n"); + HIF_SDIO_ASSERT( func ); + + //4 <0> display debug information + HIF_SDIO_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); + for (i = 0;i < func->card->num_info;i++) { + HIF_SDIO_INFO_FUNC("card->info[%d]: %s\n", i, func->card->info[i]); + } + + //4 <1> Check if this is supported by us (mtk_sdio_id_tbl) + ret = hif_sdio_check_supported_sdio_id( func->vendor, func->device ); + if (ret) { + HIF_SDIO_WARN_FUNC("vendor id and device id of sdio_func are not supported in mtk_sdio_id_tbl!\n"); + goto out; + } + + //4 <2> Add this struct sdio_func *func to g_hif_sdio_probed_func_list + for( i=0; ifunc = func; + hif_sdio_probed_funcp->clt_idx = hif_sdio_find_clt_list_index(func->vendor, func->device, func->num); + hif_sdio_probed_funcp->on_by_wmt = MTK_WCN_BOOL_FALSE; + /* probed spin unlock */ + spin_unlock_bh( &g_hif_sdio_lock_info.probed_list_lock ); + probe_index = i; + break; + } + else + { + /* probed spin unlock */ + spin_unlock_bh( &g_hif_sdio_lock_info.probed_list_lock ); + } + } + if ( (probe_index < 0) || (probe_index >= CFG_CLIENT_COUNT) ) + { + HIF_SDIO_ERR_FUNC("probe function list if full!\n"); + goto out; + } + + //4 <3> Initialize this function + if ( g_hif_sdio_probed_func_list[probe_index].clt_idx < 0 ) + { + for( i=0; imanf_id, g_hif_sdio_clt_drv_list[i].func_info->card_id, g_hif_sdio_clt_drv_list[i].func_info->func_num ); + if ( (g_hif_sdio_clt_drv_list[i].func_info->manf_id == g_hif_sdio_probed_func_list[probe_index].func->vendor)&&\ + (g_hif_sdio_clt_drv_list[i].func_info->card_id == g_hif_sdio_probed_func_list[probe_index].func->device)&&\ + (g_hif_sdio_clt_drv_list[i].func_info->func_num == g_hif_sdio_probed_func_list[probe_index].func->num) ) + { + g_hif_sdio_probed_func_list[probe_index].clt_idx = i; + // client list spin unlock + spin_unlock_bh( &g_hif_sdio_lock_info.clt_list_lock ); + break; + } + else + { + // client list spin unlock + spin_unlock_bh( &g_hif_sdio_lock_info.clt_list_lock ); + } + } + HIF_SDIO_INFO_FUNC("map to g_hif_sdio_clt_drv_list[] done: %d\n", g_hif_sdio_probed_func_list[probe_index].clt_idx ); + } + + //4 <3.1> enable this function + sdio_claim_host(func); + ret = sdio_enable_func(func); + sdio_release_host(func); + if (ret) { + HIF_SDIO_ERR_FUNC("sdio_enable_func failed!\n"); + goto out; + } + + //4 <3.2> set block size according to the table storing function characteristics + if ( hif_sdio_probed_funcp == 0 ) + { + HIF_SDIO_ERR_FUNC("hif_sdio_probed_funcp is null!\n"); + goto out; + } + if ( hif_sdio_probed_funcp->clt_idx >= 0 ) /* The clt contex has been registed */ + { + sdio_claim_host(func); + ret = sdio_set_block_size(func, g_hif_sdio_clt_drv_list[hif_sdio_probed_funcp->clt_idx].func_info->blk_sz); + sdio_release_host(func); + } + else /* The clt contex has not been registed */ + { + sdio_claim_host(func); + ret = sdio_set_block_size(func, HIF_DEFAULT_BLK_SIZE); + sdio_release_host(func); + } + if (ret) { + HIF_SDIO_ERR_FUNC("set sdio block size failed!\n"); + goto out; + } + + HIF_SDIO_INFO_FUNC("cur_blksize(%d) max(%d), host max blk_size(%d) blk_count(%d)\n", + func->cur_blksize, func->max_blksize, + func->card->host->max_blk_size, func->card->host->max_blk_count + ); + + // TODO:[ChangeFeature][George]: explain why this block is marked +#if 0 + //4 <3.3> claim irq for this function + sdio_claim_host(func); + ret = sdio_claim_irq(func, hif_sdio_irq); + sdio_release_host(func); + printk(KERN_INFO "sdio_claim_irq ret=%d\n", ret); + + //4 <3.4> If this struct sdio_func *func is supported by any driver in + //4 g_hif_sdio_clt_drv_list, schedule another task to call client's .hif_clt_probe() + if ( (clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx) >= 0 ) /* the function has been registered */ + { + /* use worker thread to perform the client's .hif_clt_probe() */ + clt_probe_worker_info = vmalloc( sizeof(MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO) ); + INIT_WORK( &clt_probe_worker_info->probe_work, hif_sdio_clt_probe_worker ); + clt_probe_worker_info->registinfo_p = &g_hif_sdio_clt_drv_list[clt_index]; + clt_probe_worker_info->probe_idx = probe_index; + schedule_work( &clt_probe_worker_info->probe_work ); + } +#endif + + hif_sdio_dump_probe_list(); + +out: + //4 error handling + return ret; +} + + +/*! + * \brief hif_sdio remove function + * + * hif_sdio probe function called by mmc driver when the probed func should be + * removed. + * + * \param func + * + */ +static void hif_sdio_remove ( + struct sdio_func *func + ) +{ + int probed_list_index = 0; +#if 0 + int registed_list_index = 0; +#endif + + HIF_SDIO_INFO_FUNC("start!\n"); + HIF_SDIO_ASSERT( func ); + + //4 <1> check input parameter is valid and has been probed previously + if (func == NULL) { + HIF_SDIO_ERR_FUNC("func null(%p)\n", func); + return; + } + + //4 <2> if this function has been initialized by any client driver, + //4 call client's .hif_clt_remove() call back in THIS context. + probed_list_index = hif_sdio_find_probed_list_index_by_func( func ); + if ( probed_list_index < 0 ) + { + HIF_SDIO_WARN_FUNC("sdio function pointer is not in g_hif_sdio_probed_func_list!\n"); + return; + } +#if 0 + registed_list_index = g_hif_sdio_probed_func_list[probed_list_index].clt_idx; + if ( registed_list_index >= 0 ) + { + g_hif_sdio_clt_drv_list[registed_list_index].sdio_cltinfo->hif_clt_remove( CLTCTX(func->device, func->num,\ + func->cur_blksize, probed_list_index) ); + } +#endif + + //4 <3> mark this function as de-initialized and invalidate client's context + hif_sdio_init_probed_list(probed_list_index); + +#if 0 + //4 <4> release irq for this function + sdio_claim_host(func); + sdio_release_irq(func); + sdio_release_host(func); +#endif + + //4 <5> disable this function + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + //4 <6> mark this function as removed + + HIF_SDIO_INFO_FUNC("sdio func(0x%p) is removed successfully!\n", func); +} + +/*! + * \brief hif_sdio interrupt handler + * + * detailed descriptions + * + * \param ctx client's context variable + * + */ +static void hif_sdio_irq ( + struct sdio_func *func + ) +{ + int probed_list_index = -1; + int registed_list_index = -1; + + HIF_SDIO_DBG_FUNC("start!\n"); + HIF_SDIO_DBG_FUNC("add by zhiguo%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"); + //4 <1> check if func is valid + HIF_SDIO_ASSERT( func ); + + //4 <2> if func has valid corresponding hif_sdio client's context, mark it + //4 host-locked, use it to call client's .hif_clt_irq() callback function in + //4 THIS context. + probed_list_index = hif_sdio_find_probed_list_index_by_func( func ); + if ( (probed_list_index < 0) || (probed_list_index >= CFG_CLIENT_COUNT) ) + { + HIF_SDIO_ERR_FUNC("probed_list_index not found!\n"); + return; + } + + registed_list_index = g_hif_sdio_probed_func_list[probed_list_index].clt_idx; +// g_hif_sdio_probed_func_list[probed_list_index].interrupted = MTK_WCN_BOOL_TRUE; + if ( (registed_list_index >= 0) + && (registed_list_index < CFG_CLIENT_COUNT) ) { + g_hif_sdio_clt_drv_list[registed_list_index].sdio_cltinfo->hif_clt_irq( CLTCTX(func->device,\ + func->num, func->cur_blksize, probed_list_index) ); + } + else { + //4 <3> if func has no VALID hif_sdio client's context, release irq for this + //4 func and mark it in g_hif_sdio_probed_func_list (remember: donnot claim host in irq contex). + HIF_SDIO_WARN_FUNC("release irq (func:0x%p) v(0x%x) d(0x%x) n(0x%x)\n", + func, func->vendor, func->device, func->num); + sdio_release_irq(func); + } + + return; +} + +/*! + * \brief hif_sdio init function + * + * detailed descriptions + * + * \retval + */ +static int __init hif_sdio_init(void) +{ + int ret = 0; + INT32 i = 0; + + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <1> init all private variables + /* init reference count to 0 */ + gRefCount = 0; + + /* init spin lock information */ + spin_lock_init( &g_hif_sdio_lock_info.probed_list_lock ); + spin_lock_init( &g_hif_sdio_lock_info.clt_list_lock ); + + /* init probed function list and g_hif_sdio_clt_drv_list */ + for ( i=0; i register to mmc driver + ret = sdio_register_driver(&mtk_sdio_client_drv); + HIF_SDIO_INFO_FUNC("sdio_register_driver() ret=%d\n", ret); + + HIF_SDIO_DBG_FUNC("end!\n"); + return ret; +} + +/*! + * \brief hif_sdio init function + * + * detailed descriptions + * + * \retval + */ +static VOID __exit hif_sdio_exit(void) +{ + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <0> if client driver is not removed yet, we shall NOT be called... + + //4 <1> check reference count + if ( gRefCount !=0 ) + { + HIF_SDIO_WARN_FUNC("gRefCount=%d !!!\n", gRefCount); + } + + //4 <2> check if there is any hif_sdio-registered clients. There should be + //4 no registered client... + + //4 <3> Reregister with mmc driver. Our remove handler hif_sdio_remove() + //4 will be called later by mmc_core. Clean up driver resources there. + sdio_unregister_driver(&mtk_sdio_client_drv); + + HIF_SDIO_DBG_FUNC("end!\n"); + return; +} /* end of exitWlan() */ + +/*! + * \brief stp on by wmt (probe client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already on, -13:not registered, other errors. + */ +INT32 hif_sdio_stp_on( + void + ) +{ +#if 0 + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; +#endif + INT32 clt_index = -1; + INT32 probe_index = -1; + struct sdio_func *func = 0; + int ret; + int ret2; + + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <1> If stp client drv has not been probed, return error code + /* MT6620 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020B, 1)) >= 0 ) + { + goto stp_on_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 1)) >= 0 ) + { + goto stp_on_exist; + } + + /* MT6619 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6619, 1)) >= 0 ) + { + goto stp_on_exist; + } + + /* MT6618 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018B, 1)) >= 0 ) + { + goto stp_on_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 1)) >= 0 ) + { + goto stp_on_exist; + } + else + { + //4 <2> If stp client drv has not been probed, return error code + /* client func has not been probed */ + HIF_SDIO_INFO_FUNC("no supported func probed \n"); + return HIF_SDIO_ERR_NOT_PROBED; + } + +stp_on_exist: + //4 <3> If stp client drv has been on by wmt, return error code + if (MTK_WCN_BOOL_FALSE != g_hif_sdio_probed_func_list[probe_index].on_by_wmt) { + HIF_SDIO_INFO_FUNC("already on...\n"); + return HIF_SDIO_ERR_ALRDY_ON; + } + else { + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_TRUE; + } + + if ( (clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx) >= 0 ) /* the function has been registered */ + { + /* [George] mark disabled before sdio_claim_irq(), set enabled later by + * client driver call mtk_wcn_hif_sdio_enable_irq() in their probe(). + */ + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + smp_wmb(); + HIF_SDIO_DBG_FUNC("probe_index(%d) sdio irq enable(0)\n", probe_index); + + //4 <4> claim irq for this function + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_claim_irq(func, hif_sdio_irq); + sdio_release_host(func); + if (ret) { + HIF_SDIO_WARN_FUNC("sdio_claim_irq() for stp fail(%d)\n", ret); + return ret; + } + HIF_SDIO_INFO_FUNC("sdio_claim_irq() for stp ok\n"); + + //4 <5> If this struct sdio_func *func is supported by any driver in + //4 g_hif_sdio_clt_drv_list, schedule another task to call client's .hif_clt_probe() + // TODO: [FixMe][George] WHY probe worker is removed??? +#if 1 + /* Call client's .hif_clt_probe() */ + ret = hif_sdio_clt_probe_func(&g_hif_sdio_clt_drv_list[clt_index], probe_index); + if (ret) { + HIF_SDIO_WARN_FUNC("clt_probe_func() for stp fail(%d) release irq\n", ret); + sdio_claim_host(func); + ret2 = sdio_release_irq(func); + sdio_release_host(func); + if (ret2) { + HIF_SDIO_WARN_FUNC("sdio_release_irq() for stp fail(%d)\n", ret2); + } + + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + return ret; + } + HIF_SDIO_INFO_FUNC("ok!\n"); + + return 0; +#else + /* use worker thread to perform the client's .hif_clt_probe() */ + clt_probe_worker_info = vmalloc( sizeof(MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO) ); + INIT_WORK( &clt_probe_worker_info->probe_work, hif_sdio_clt_probe_worker ); + clt_probe_worker_info->registinfo_p = &g_hif_sdio_clt_drv_list[clt_index]; + clt_probe_worker_info->probe_idx = probe_index; + schedule_work( &clt_probe_worker_info->probe_work ); +#endif + } + else { + // TODO: [FixMe][George] check if clt_index is cleared in client's unregister function + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + return HIF_SDIO_ERR_CLT_NOT_REG; + } +} + +/*! + * \brief stp off by wmt (remove client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already off, -13:not registered, other errors. + */ +INT32 hif_sdio_stp_off( + void + ) +{ + INT32 clt_index = -1; + INT32 probe_index = -1; + struct sdio_func *func = 0; + int ret = -1; + int ret2 = -1; + + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <1> If stp client drv has not been probed, return error code + /* MT6620 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020B, 1)) >= 0 ) + { + goto stp_off_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 1)) >= 0 ) + { + goto stp_off_exist; + } + + /* MT6619 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x6619, 1)) >= 0 ) + { + goto stp_off_exist; + } + + /* MT6618 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018B, 1)) >= 0 ) + { + goto stp_off_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 1)) >= 0 ) + { + goto stp_off_exist; + } + else + { + //4 <2> If stp client drv has not been probed, return error code + /* client func has not been probed */ + return HIF_SDIO_ERR_NOT_PROBED; + } + +stp_off_exist: + //4 <3> If stp client drv has been off by wmt, return error code + if (MTK_WCN_BOOL_FALSE == g_hif_sdio_probed_func_list[probe_index].on_by_wmt) { + HIF_SDIO_WARN_FUNC("already off...\n"); + return HIF_SDIO_ERR_ALRDY_OFF; + } + else { + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + } + +#if 0 // TODO: [FixMe][George] moved below as done in stp_on. + //4 <4> release irq for this function + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_release_irq(func); + sdio_release_host(func); + if (ret) { + printk(KERN_WARNING DRV_NAME "sdio_release_irq for stp fail(%d)\n", ret); + } + else { + printk(KERN_INFO DRV_NAME "sdio_release_irq for stp ok\n"); + } +#endif + + if ( (clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx) >= 0 ) /* the function has been registered */ + { + //4 <4> release irq for this function + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_release_irq(func); + sdio_release_host(func); + + if (ret) { + HIF_SDIO_WARN_FUNC("sdio_release_irq() for stp fail(%d)\n", ret); + } + else { + HIF_SDIO_INFO_FUNC("sdio_release_irq() for stp ok\n"); + } + /* [George] mark disabled after sdio_release_irq(). */ + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + smp_wmb(); + HIF_SDIO_DBG_FUNC("probe_index(%d) sdio irq enable(0)\n", probe_index); + + //4 <5> Callback to client driver's remove() func + ret2 = g_hif_sdio_clt_drv_list[clt_index].sdio_cltinfo->hif_clt_remove( + CLTCTX(func->device, func->num, func->cur_blksize, probe_index) ); + if (ret2) { + HIF_SDIO_WARN_FUNC("clt_remove for stp fail(%d)\n", ret2); + } + else { + HIF_SDIO_INFO_FUNC("ok!\n"); + } + + return (ret + ret2); + } + else { + // TODO: [FixMe][George] check if clt_index is cleared in client's unregister function + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + return HIF_SDIO_ERR_CLT_NOT_REG; + } +} + +/*! + * \brief wifi on by wmt (probe client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already on, -13:not registered, other errors. + */ +INT32 +hif_sdio_wifi_on (void) +{ +#if 0 + MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO *clt_probe_worker_info = 0; +#endif + INT32 clt_index = -1; + INT32 probe_index = -1; + struct sdio_func *func = 0; + int ret; + int ret2; + + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <1> If wifi client drv has not been probed, return error code + /* MT6620 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020A, 1)) >= 0 ) + { + goto wifi_on_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 2)) >= 0 ) + { + goto wifi_on_exist; + } + + /* MT6618 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018A, 1)) >= 0 ) + { + goto wifi_on_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 2)) >= 0 ) + { + goto wifi_on_exist; + } + else + { + //4 <2> If wifi client drv has not been probed, return error code + /* client func has not been probed */ + return HIF_SDIO_ERR_NOT_PROBED; + } + +wifi_on_exist: + //4 <3> If wifi client drv has been on by wmt, return error code + if (g_hif_sdio_probed_func_list[probe_index].on_by_wmt) { + HIF_SDIO_INFO_FUNC("probe_index (%d), already on...\n", probe_index); + return HIF_SDIO_ERR_ALRDY_ON; + } + + if ( (clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx) >= 0 ) /* the function has been registered */ + { + /* [George] mark disabled before sdio_claim_irq(), set enabled later by + * client driver call mtk_wcn_hif_sdio_enable_irq() in their probe(). + */ + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + smp_wmb(); + HIF_SDIO_DBG_FUNC("probe_index(%d) sdio irq enable(0)\n", probe_index); + + //4 <4> claim irq for this function + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_claim_irq(func, hif_sdio_irq); + sdio_release_host(func); + if (ret) { + HIF_SDIO_WARN_FUNC("sdio_claim_irq() for wifi fail(%d)\n", ret); + return ret; + } + HIF_SDIO_INFO_FUNC("sdio_claim_irq() for wifi ok\n"); + + //4 <5> If this struct sdio_func *func is supported by any driver in + //4 g_hif_sdio_clt_drv_list, schedule another task to call client's .hif_clt_probe() + // TODO: [FixMe][George] WHY probe worker is removed??? +#if 1 + /* Call client's .hif_clt_probe() */ + ret = hif_sdio_clt_probe_func(&g_hif_sdio_clt_drv_list[clt_index], probe_index); + if (ret) { + HIF_SDIO_WARN_FUNC("clt_probe_func() for wifi fail(%d) release irq\n", ret); + sdio_claim_host(func); + ret2 = sdio_release_irq(func); + sdio_release_host(func); + if (ret2) { + HIF_SDIO_WARN_FUNC("sdio_release_irq() for wifi fail(%d)\n", ret2); + } + + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + return ret; + } + else + { + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_TRUE; + } + HIF_SDIO_INFO_FUNC("ok!\n"); + return 0; +#else + /* use worker thread to perform the client's .hif_clt_probe() */ + clt_probe_worker_info = vmalloc( sizeof(MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO) ); + INIT_WORK( &clt_probe_worker_info->probe_work, hif_sdio_clt_probe_worker ); + clt_probe_worker_info->registinfo_p = &g_hif_sdio_clt_drv_list[clt_index]; + clt_probe_worker_info->probe_idx = probe_index; + schedule_work( &clt_probe_worker_info->probe_work ); +#endif + } + else { + // TODO: [FixMe][George] check if clt_index is cleared in client's unregister function + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + return HIF_SDIO_ERR_CLT_NOT_REG; + } +} + +/*! + * \brief wifi off by wmt (remove client driver). + * + * + * \param none. + * + * \retval 0:success, -11:not probed, -12:already off, -13:not registered, other errors. + */ +INT32 hif_sdio_wifi_off( + void + ) +{ + INT32 clt_index = -1; + INT32 probe_index = -1; + struct sdio_func *func = 0; + int ret = -1; + int ret2 = -1; + + HIF_SDIO_INFO_FUNC("start!\n"); + + //4 <1> If wifi client drv has not been probed, return error code + /* MT6620 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020A, 1)) >= 0 ) + { + goto wifi_off_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x020C, 2)) >= 0 ) + { + goto wifi_off_exist; + } + + /* MT6618 */ + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018A, 1)) >= 0 ) + { + goto wifi_off_exist; + } + if ( (probe_index = hif_sdio_find_probed_list_index_by_id_func(0x037A, 0x018C, 2)) >= 0 ) + { + goto wifi_off_exist; + } + else + { + //4 <2> If wifi client drv has not been probed, return error code + /* client func has not been probed */ + return HIF_SDIO_ERR_NOT_PROBED; + } + +wifi_off_exist: + //4 <3> If wifi client drv has been off by wmt, return error code + if (MTK_WCN_BOOL_FALSE == g_hif_sdio_probed_func_list[probe_index].on_by_wmt) { + HIF_SDIO_WARN_FUNC("already off...\n"); + return HIF_SDIO_ERR_ALRDY_OFF; + } + else { + g_hif_sdio_probed_func_list[probe_index].on_by_wmt = MTK_WCN_BOOL_FALSE; + } + +#if 0 // TODO: [FixMe][George] moved below as done in wifi_on. + //4 <4> release irq for this function + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_release_irq(func); + sdio_release_host(func); + if (ret) { + printk(KERN_WARNING DRV_NAME "sdio_release_irq for wifi fail(%d)\n", ret); + } + else { + printk(KERN_INFO DRV_NAME "sdio_release_irq for wifi ok\n"); + } +#endif + + if ( (clt_index = g_hif_sdio_probed_func_list[probe_index].clt_idx) >= 0 ) /* the function has been registered */ + { + //4 <4> release irq for this function + func = g_hif_sdio_probed_func_list[probe_index].func; + sdio_claim_host(func); + ret = sdio_release_irq(func); + sdio_release_host(func); + if (ret) { + HIF_SDIO_WARN_FUNC("sdio_release_irq() for wifi fail(%d)\n", ret); + } + else { + HIF_SDIO_INFO_FUNC("sdio_release_irq() for wifi ok\n"); + } + /* [George] mark disabled after sdio_release_irq(). */ + g_hif_sdio_probed_func_list[probe_index].sdio_irq_enabled = MTK_WCN_BOOL_FALSE; + smp_wmb(); + HIF_SDIO_DBG_FUNC("probe_index(%d) sdio irq enable(0)\n", probe_index); + + //4 <5> Callback to client driver's remove() func + ret2 = g_hif_sdio_clt_drv_list[clt_index].sdio_cltinfo->hif_clt_remove( + CLTCTX(func->device, func->num, func->cur_blksize, probe_index) ); + if (ret2) { + HIF_SDIO_WARN_FUNC("clt_remove for wifi fail(%d)\n", ret2); + } + else { + HIF_SDIO_INFO_FUNC("ok!\n"); + } + + return (ret + ret2); + } + else { + // TODO: [FixMe][George] check if clt_index is cleared in client's unregister function + HIF_SDIO_WARN_FUNC("probed but not registered yet (%d)\n", ret); + return HIF_SDIO_ERR_CLT_NOT_REG; + } +} + +module_init(hif_sdio_init); +module_exit(hif_sdio_exit); + +EXPORT_SYMBOL(mtk_wcn_hif_sdio_client_reg); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_client_unreg); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_readb); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_writeb); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_readl); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_writel); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_read_buf); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_write_buf); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_set_drvdata); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_get_drvdata); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_wmt_control); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_get_dev); +EXPORT_SYMBOL(mtk_wcn_hif_sdio_enable_irq); + diff --git a/drivers/mtk_wcn_combo/common/linux/hw_chrdev_test.c b/drivers/mtk_wcn_combo/common/linux/hw_chrdev_test.c new file mode 100755 index 000000000000..98f4641d9f6e --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/hw_chrdev_test.c @@ -0,0 +1,611 @@ +/****************************************************************************** +* C O M P I L E R F L A G S +******************************************************************************* +*/ + +/****************************************************************************** +* E X T E R N A L R E F E R E N C E S +******************************************************************************* +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//for mtk +//#include +//#include +//#include +//end for mtk + +//for Ingenic +#include +#include +#include +#include +//end for Ingenic + +#include "hw_test.h" + +/****************************************************************************** +* C O N S T A N T S +******************************************************************************* +*/ +#define GPIO_PMU_PIN GPD27 +#define GPIO_RST_PIN GPD29 +#define GPIO_RTC_PIN GPD14 +#define GPIO_BGF_INT GPF20 +#define GPIO_WIF_INT GPF21 + +#define HWTEST_DEV_MAJOR 194 // never used number +#define HWTEST_DEV_NUM 1 + +/* Linux char device */ +static int HWTEST_major = HWTEST_DEV_MAJOR; +static struct cdev HWTEST_cdev; +static atomic_t HWTEST_ref_cnt = ATOMIC_INIT(0); + +unsigned char** g_read_card_info_bysdio; +unsigned char** g_test; + +UINT8 g_read_current_io_isready_from_sdio_card; +UINT16 g_read_function_blksize_from_sdio_card; +UINT32 g_read_int_from_sdio_card; + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#define HWTEST_SUPPORT_PHONE 0 +#define HWTEST_SUPPORT_SDIO 1 + + +int porting_6620_sdio_card_detect() +{ + int ret = -1; + //for MTK + //ret = mt_combo_sdio_ctrl(2,1); + //end for MTK + //for Ingenic + ret = sdio_card_detect(); + //end for Ingenic + if(!ret){ + return 0; + }else{ + HWTEST_INFO_FUNC("sdio card detect fail"); + return -1; + } +} +int porting_6620_sdio_card_remove() +{ + int ret = -1; + //for MTK + //ret = mt_combo_sdio_ctrl(2,0); + //end for MTK + //for Ingenic + ret = sdio_card_remove(); + //end for Ingenic + if(!ret){ + return 0; + }else{ + HWTEST_INFO_FUNC("sdio card remove fail"); + return -1; + } +} +//end for Ingenic + +int chip_power_on(void) +{ + //int ret = -1; +#define MT6620_OFF_TIME (10) /* in ms, workable value */ +#define MT6620_RST_TIME (30) /* in ms, workable value */ +#define MT6620_STABLE_TIME (30) /* in ms, workable value */ +#define MT6620_EXT_INT_TIME (5) /* in ms, workable value */ +#define MT6620_32K_STABLE_TIME (100) /* in ms, test value */ + +#if 0 +#if (HWTEST_SUPPORT_PHONE) + /* disable pull */ + mt_set_gpio_pull_enable(GPIO_COMBO_6620_LDO_EN_PIN, GPIO_PULL_DISABLE); + /* set output */ + mt_set_gpio_dir(GPIO_COMBO_6620_LDO_EN_PIN, GPIO_DIR_OUT); + /* set gpio mode */ + mt_set_gpio_mode(GPIO_COMBO_6620_LDO_EN_PIN, GPIO_MODE_GPIO); + /* external LDO_EN high */ + mt_set_gpio_out(GPIO_COMBO_6620_LDO_EN_PIN, GPIO_OUT_ONE); +#endif + +#if (HWTEST_SUPPORT_SDIO) && (CONFIG_MTK_COMBO_SDIO_SLOT == 0) + printk(KERN_INFO "[mt6620] pull up sd0 bus(gpio169~gpio175(exclude gpio174))\n"); + mt_set_gpio_pull_enable(GPIO172, GPIO_PULL_ENABLE); //->CLK + mt_set_gpio_pull_select(GPIO172, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO171, GPIO_PULL_ENABLE); //->CMD + mt_set_gpio_pull_select(GPIO171, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO175, GPIO_PULL_ENABLE); //->DAT0 + mt_set_gpio_pull_select(GPIO175, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO173, GPIO_PULL_ENABLE); //->DAT1 + mt_set_gpio_pull_select(GPIO173, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO169, GPIO_PULL_ENABLE); //->DAT2 + mt_set_gpio_pull_select(GPIO169, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO170, GPIO_PULL_ENABLE); //->DAT3 + mt_set_gpio_pull_select(GPIO170, GPIO_PULL_UP); +#elif (CONFIG_MTK_COMBO_SDIO_SLOT == 1) + #error "error:MSDC1 is not reserved for MT6620 on MT6575EVB" +#elif (CONFIG_MTK_COMBO_SDIO_SLOT == 2) + printk(KERN_INFO "[mt6620] pull up sd2 bus(gpio182~187)\n"); + mt_set_gpio_pull_enable(GPIO182, GPIO_PULL_ENABLE); //->CLK + mt_set_gpio_pull_select(GPIO182, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO184, GPIO_PULL_ENABLE); //->CMD + mt_set_gpio_pull_select(GPIO184, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO186, GPIO_PULL_ENABLE); //->DAT0 + mt_set_gpio_pull_select(GPIO186, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO187, GPIO_PULL_ENABLE); //->DAT1 + mt_set_gpio_pull_select(GPIO187, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO185, GPIO_PULL_ENABLE); //->DAT2 + mt_set_gpio_pull_select(GPIO185, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO183, GPIO_PULL_ENABLE); //->DAT3 + mt_set_gpio_pull_select(GPIO183, GPIO_PULL_UP); +#elif (CONFIG_MTK_COMBO_SDIO_SLOT == 3) + printk(KERN_INFO "[mt6620] pull up sd3 bus (GPIO89~GPIO94)\n"); + mt_set_gpio_pull_enable(GPIO92, GPIO_PULL_ENABLE); //->CLK + mt_set_gpio_pull_select(GPIO92, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO91, GPIO_PULL_ENABLE); //->CMD + mt_set_gpio_pull_select(GPIO91, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO94, GPIO_PULL_ENABLE); //->DAT0 + mt_set_gpio_pull_select(GPIO94, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO90, GPIO_PULL_ENABLE); //->DAT1 + mt_set_gpio_pull_select(GPIO90, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_ENABLE); //->DAT2 + mt_set_gpio_pull_select(GPIO89, GPIO_PULL_UP); + mt_set_gpio_pull_enable(GPIO93, GPIO_PULL_ENABLE); //->DAT3 + mt_set_gpio_pull_select(GPIO93, GPIO_PULL_UP); +#else + #error "error:unsupported CONFIG_MTK_COMBO_SDIO_SLOT" CONFIG_MTK_COMBO_SDIO_SLOT +#endif + + /* UART Mode */ + ret = mt_set_gpio_mode(GPIO_UART_URXD3_PIN, GPIO_UART_URXD3_PIN_M_URXD);//GPIO_MODE_01->GPIO_UART_URXD3_PIN_M_URXD + ret += mt_set_gpio_mode(GPIO_UART_UTXD3_PIN, GPIO_UART_UTXD3_PIN_M_UTXD);//GPIO_MODE_01->GPIO_UART_UTXD3_PIN_M_UTXD + //printk(KERN_INFO "[mt6620] set UART GPIO Mode [%d]\n", result); + + /* disable pull */ +#if (HWTEST_SUPPORT_PHONE) + mt_set_gpio_pull_enable(GPIO25, GPIO_PULL_DISABLE); +#endif + ret += mt_set_gpio_pull_enable(GPIO_COMBO_PMU_EN_PIN, GPIO_PULL_DISABLE); + ret += mt_set_gpio_pull_enable(GPIO_COMBO_RST_PIN, GPIO_PULL_DISABLE); + + /* set output */ +#if (HWTEST_SUPPORT_PHONE) + mt_set_gpio_dir(GPIO25, GPIO_DIR_OUT); +#endif + ret += mt_set_gpio_dir(GPIO_COMBO_PMU_EN_PIN, GPIO_DIR_OUT); + ret += mt_set_gpio_dir(GPIO_COMBO_RST_PIN, GPIO_DIR_OUT); + + /* set gpio mode */ +#if defined(HWTEST_SUPPORT_PHONE) + mt_set_gpio_mode(GPIO25, GPIO_MODE_GPIO); +#endif + ret += mt_set_gpio_mode(GPIO_COMBO_PMU_EN_PIN, GPIO_MODE_GPIO); + ret += mt_set_gpio_mode(GPIO_COMBO_RST_PIN, GPIO_MODE_GPIO); + + /* SYSRST_B low */ + ret += mt_set_gpio_out(GPIO_COMBO_RST_PIN, GPIO_OUT_ZERO); + /* PMU_EN low */ +#if (HWTEST_SUPPORT_PHONE) + mt_set_gpio_out(GPIO25, GPIO_OUT_ZERO); +#endif + ret += mt_set_gpio_out(GPIO_COMBO_PMU_EN_PIN, GPIO_OUT_ZERO); + + msleep(MT6620_OFF_TIME); + + /* PMU_EN high, SYSRST_B low */ +#if (HWTEST_SUPPORT_PHONE) + mt_set_gpio_out(GPIO25, GPIO_OUT_ONE); +#endif + ret += mt_set_gpio_out(GPIO_COMBO_PMU_EN_PIN, GPIO_OUT_ONE); + msleep(MT6620_RST_TIME); + + /* SYSRST_B high */ + ret += mt_set_gpio_out(GPIO_COMBO_RST_PIN, GPIO_OUT_ONE); + msleep(MT6620_STABLE_TIME); +#endif + + //for Ingenic + rtc_enable_clk32k(); + msleep(MT6620_32K_STABLE_TIME); + __gpio_as_uart2(); + msleep(30); + + //PMU_EN-->0 + __gpio_enable_pull(GPIO_PMU_PIN); + __gpio_as_output(GPIO_PMU_PIN); + __gpio_clear_pin(GPIO_PMU_PIN); + //RST-->0 + __gpio_enable_pull(GPIO_RST_PIN); + __gpio_as_output(GPIO_RST_PIN); + __gpio_clear_pin(GPIO_RST_PIN); + + msleep(MT6620_OFF_TIME); + //PMU_EN-->1 + __gpio_set_pin(GPIO_PMU); + msleep(MT6620_RST_TIME); + + __gpio_enable_pull(GPIO_RST_PIN); + __gpio_as_output(GPIO_RST_PIN); + __gpio_set_pin(GPIO_RST_PIN); + + msleep(MT6620_STABLE_TIME); + printk(KERN_INFO "[mt6620] power on \n"); + + return 0; +} + + +int chip_power_off(void) +{ + //int ret = -1; + printk(KERN_INFO "[mt6620] power off\n"); +#if 0 + /* SYSRST_B low */ + mt_set_gpio_out(GPIO_COMBO_RST_PIN, GPIO_OUT_ZERO); + /* PMU_EN low */ +#if (HWTEST_SUPPORT_PHONE) + mt_set_gpio_out(GPIO25, GPIO_OUT_ZERO); +#endif + mt_set_gpio_out(GPIO_COMBO_PMU_EN_PIN, GPIO_OUT_ZERO); + +#if (HWTEST_SUPPORT_SDIO) && (CONFIG_MTK_COMBO_SDIO_SLOT == 0) + printk(KERN_INFO "[mt6620] pull down sd0 bus(gpio169~gpio175(exclude gpio174))\n"); + mt_set_gpio_pull_enable(GPIO172, GPIO_PULL_DOWN); //->CLK + mt_set_gpio_pull_select(GPIO172, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO171, GPIO_PULL_DOWN); //->CMD + mt_set_gpio_pull_select(GPIO171, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO175, GPIO_PULL_DOWN); //->DAT0 + mt_set_gpio_pull_select(GPIO175, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO173, GPIO_PULL_DOWN); //->DAT1 + mt_set_gpio_pull_select(GPIO173, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO169, GPIO_PULL_DOWN); //->DAT2 + mt_set_gpio_pull_select(GPIO169, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO170, GPIO_PULL_DOWN); //->DAT3 + mt_set_gpio_pull_select(GPIO170, GPIO_PULL_ENABLE); +#elif (CONFIG_MTK_COMBO_SDIO_SLOT == 1) + #error "error:MSDC1 is not reserved for MT6620 on MT6575EVB" +#elif (CONFIG_MTK_COMBO_SDIO_SLOT == 2) + printk(KERN_INFO "[mt6620] pull down sd2 bus(gpio182~187)\n"); + mt_set_gpio_pull_enable(GPIO182, GPIO_PULL_DOWN); //->CLK + mt_set_gpio_pull_select(GPIO182, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO184, GPIO_PULL_DOWN); //->CMD + mt_set_gpio_pull_select(GPIO184, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO186, GPIO_PULL_DOWN); //->DAT0 + mt_set_gpio_pull_select(GPIO186, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO187, GPIO_PULL_DOWN); //->DAT1 + mt_set_gpio_pull_select(GPIO187, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO185, GPIO_PULL_DOWN); //->DAT2 + mt_set_gpio_pull_select(GPIO185, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO183, GPIO_PULL_DOWN); //->DAT3 + mt_set_gpio_pull_select(GPIO183, GPIO_PULL_ENABLE); +#elif (CONFIG_MTK_COMBO_SDIO_SLOT == 3) + printk(KERN_INFO "[mt6620] pull down sd3 bus (GPIO89~GPIO94)\n"); + mt_set_gpio_pull_enable(GPIO92, GPIO_PULL_DOWN); //->CLK + mt_set_gpio_pull_select(GPIO92, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO91, GPIO_PULL_DOWN); //->CMD + mt_set_gpio_pull_select(GPIO91, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO94, GPIO_PULL_DOWN); //->DAT0 + mt_set_gpio_pull_select(GPIO94, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO90, GPIO_PULL_DOWN); //->DAT1 + mt_set_gpio_pull_select(GPIO90, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO89, GPIO_PULL_DOWN); //->DAT2 + mt_set_gpio_pull_select(GPIO89, GPIO_PULL_ENABLE); + mt_set_gpio_pull_enable(GPIO93, GPIO_PULL_DOWN); //->DAT3 + mt_set_gpio_pull_select(GPIO93, GPIO_PULL_ENABLE); +#else + #error "error:unsupported CONFIG_MTK_COMBO_SDIO_SLOT" CONFIG_MTK_COMBO_SDIO_SLOT +#endif + + + //printk(KERN_INFO "[mt6620] set UART GPIO Mode output 0\n"); + ret = mt_set_gpio_mode(GPIO_UART_URXD3_PIN, GPIO_UART_URXD3_PIN_M_GPIO); + ret += mt_set_gpio_dir(GPIO_UART_URXD3_PIN, GPIO_DIR_OUT); + ret += mt_set_gpio_out(GPIO_UART_URXD3_PIN, GPIO_OUT_ZERO); + + ret += mt_set_gpio_mode(GPIO_UART_UTXD3_PIN, GPIO_UART_UTXD3_PIN_M_GPIO); + ret += mt_set_gpio_dir(GPIO_UART_UTXD3_PIN, GPIO_DIR_OUT); + ret += mt_set_gpio_out(GPIO_UART_UTXD3_PIN, GPIO_OUT_ZERO); + +#if (HWTEST_SUPPORT_PHONE) + mt_set_gpio_out(GPIO_COMBO_6620_LDO_EN_PIN, GPIO_OUT_ZERO); +#endif +#endif + //for Ingenic + printk(KERN_INFO "[mt6620] power off\n"); + __gpio_clear_pin(GPIO_RST_PIN); + __gpio_clear_pin(GPIO_PMU_PIN); + rtc_disable_clk32k(); + return 0; +} + +ssize_t HWTEST_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + return 0; +} + +ssize_t HWTEST_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + int i = 0; + char local_buf[256] = {'\0'}; + + HWTEST_INFO_FUNC("read card by sdio!\n"); + + if(!g_sdio_init_count){ + HWTEST_INFO_FUNC("sdio card still not initiliaztion yet!\n"); + return -1; + } + if(!g_read_card_info_bysdio[0][0]){ + HWTEST_INFO_FUNC("read sdio card buffer is null\n"); + return -2; + } + HWTEST_INFO_FUNC("%s,%s",g_read_card_info_bysdio[0],g_read_card_info_bysdio[1]); + sprintf(local_buf,"%s\n%s",g_read_card_info_bysdio[0],g_read_card_info_bysdio[1]); + //strncpy(local_buf,g_read_card_info_bysdio[0],strlen(g_read_card_info_bysdio[0])); + + if(copy_to_user(buf,local_buf,strlen(g_read_card_info_bysdio[0]) + 1 + strlen(g_read_card_info_bysdio[1]))){ + + HWTEST_INFO_FUNC("copy info to user error!\n"); + return -3; + } + return strlen(g_read_card_info_bysdio[0]) + strlen(g_read_card_info_bysdio[1])+1; +} + +unsigned int HWTEST_poll(struct file *filp, poll_table *wait) +{ + return 0; +} +//retval:odd is exception,even is error! +int HWTEST_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + int ret; + + HWTEST_INFO_FUNC("cmd (0x%04x), arg (%d)\n", cmd, (int)arg); + + switch(cmd) { + case HWTEST_IOCTL_POWER_ON: + HWTEST_INFO_FUNC("power on!\n"); + if(g_state_flag){ + HWTEST_INFO_FUNC("already power on!\n"); + retval = 1; + }else{ + ret = chip_power_on(); + if(!ret){ + g_state_flag = 1; + HWTEST_INFO_FUNC("power on OK!\n"); + }else{ + HWTEST_INFO_FUNC("power on fail!\n"); + retval = 2; + } + } + break; + + case HWTEST_IOCTL_POWER_OFF: + HWTEST_INFO_FUNC("power off!\n"); + if(!g_state_flag){ + HWTEST_INFO_FUNC("already power off!\n"); + retval = 3; + }else{ + ret = chip_power_off(); + if(!ret){ + g_state_flag = 0; + HWTEST_INFO_FUNC("power off OK!\n"); + }else{ + HWTEST_INFO_FUNC("power off fail!\n"); + retval = 4; + } + } + break; + + case HWTEST_IOCTL_CHIP_RESET: + HWTEST_INFO_FUNC("chip reset!\n"); + if(g_state_flag){ + ret = chip_power_off(); + ret += chip_power_on(); + if(!ret){ + HWTEST_INFO_FUNC("chip reset OK!\n"); + }else{ + HWTEST_INFO_FUNC("chip rest fail!\n"); + retval = 6; + } + }else{ + HWTEST_INFO_FUNC("chip is power off now!\n"); + retval = 5; + } + break; + case HWTEST_IOCTL_SDIO_INIT: + HWTEST_INFO_FUNC("init sdio card!\n"); + if(g_sdio_init_count){ + HWTEST_INFO_FUNC("SDIO card already exist!\n"); + retval = 7; + }else{ + ret = porting_6620_sdio_card_detect(); + if(!ret){ + HWTEST_INFO_FUNC("hwtest sdio init finish!\n"); + }else{ + HWTEST_INFO_FUNC("hwtest sdio init fail!\n"); + retval = 8; + } + g_sdio_init_count = 1; + } + break; + case HWTEST_IOCTL_SDIO_REMOVE: + HWTEST_INFO_FUNC("remove sdio card!\n"); + if(!g_sdio_init_count){ + HWTEST_INFO_FUNC("sdio card not exist!\n"); + retval = 9; + }else{ + ret = porting_6620_sdio_card_remove(); + if(!ret){ + HWTEST_INFO_FUNC("hwtest sdio card remove finish!\n"); + }else{ + HWTEST_INFO_FUNC("hwtest sdio card remove fail!\n"); + retval = 10; + } + g_sdio_init_count = 0; + } + break; + case HWTEST_IOCTL_SDIO_READ_IOISREADY: + if(!g_read_current_io_isready_from_sdio_card){ + HWTEST_INFO_FUNC("sdio card current io is not ready!\n"); + retval = 11; + }else{ + if (copy_to_user((void *)arg, &g_read_current_io_isready_from_sdio_card, sizeof(g_read_current_io_isready_from_sdio_card)) < 0) { + HWTEST_INFO_FUNC("copy to user space fail!\n"); + retval = 12; + } + } + break; + case HWTEST_IOCTL_SDIO_READ_BLKSIZE: + if(!g_read_function_blksize_from_sdio_card){ + HWTEST_INFO_FUNC("sdio card current function blksize is not set!\n"); + retval = 13; + }else{ + if (copy_to_user((void *)arg, &g_read_function_blksize_from_sdio_card, sizeof(g_read_function_blksize_from_sdio_card)) < 0) { + HWTEST_INFO_FUNC("copy to user space fail!\n"); + retval = 14; + } + } + break; + case HWTEST_IOCTL_SDIO_READ_INT: + if(!g_read_int_from_sdio_card){ + HWTEST_INFO_FUNC("sdio card current register has not valuse!\n"); + retval = 15; + }else{ + if (copy_to_user((void *)arg, &g_read_int_from_sdio_card, sizeof(g_read_int_from_sdio_card)) < 0) { + HWTEST_INFO_FUNC("copy to user space fail!\n"); + retval = 16; + } + } + break; + default: + retval = -17; + HWTEST_INFO_FUNC("unknown cmd (%d)\n", cmd); + break; + } + + HWTEST_INFO_FUNC("retval = (%d)\n",retval); + return retval; +} + + + +static int HWTEST_open(struct inode *inode, struct file *file) +{ + HWTEST_INFO_FUNC("major %d minor %d (pid %d)\n", + imajor(inode), + iminor(inode), + current->pid + ); + + if (atomic_inc_return(&HWTEST_ref_cnt) == 1) { + HWTEST_INFO_FUNC("1st call \n"); + } + + return 0; +} + +static int HWTEST_close(struct inode *inode, struct file *file) +{ + HWTEST_INFO_FUNC("major %d minor %d (pid %d)\n", + imajor(inode), + iminor(inode), + current->pid + ); + + if (atomic_dec_return(&HWTEST_ref_cnt) == 0) { + HWTEST_INFO_FUNC("last call \n"); + } + + return 0; +} + + +struct file_operations HWTEST_fops = { + .open = HWTEST_open, + .release = HWTEST_close, + .read = HWTEST_read, + .write = HWTEST_write, + .unlocked_ioctl = HWTEST_unlocked_ioctl, + .poll = HWTEST_poll, +}; + + +static int HWTEST_init(void) +{ + dev_t dev = MKDEV(HWTEST_major, 0); + int cdev_err = -1; + INT32 ret = -1; + /* Prepare a char device */ + /*static allocate chrdev*/ + ret = register_chrdev_region(dev, HWTEST_DEV_NUM, HWTEST_DRIVER_NAME); + if (ret) { + HWTEST_ERR_FUNC("fail to register chrdev\n"); + return ret; + } + + cdev_init(&HWTEST_cdev, &HWTEST_fops); + HWTEST_cdev.owner = THIS_MODULE; + + cdev_err = cdev_add(&HWTEST_cdev, dev, HWTEST_DEV_NUM); + if (cdev_err) { + HWTEST_ERR_FUNC("cdev_add() fails (%d) \n", cdev_err); + goto error; + } + + HWTEST_INFO_FUNC("driver(major %d) installed \n", HWTEST_major); + + HWTEST_INFO_FUNC("success \n"); + return 0; + +error: + + if (cdev_err == 0) { + cdev_del(&HWTEST_cdev); + } + + if (ret == 0) { + unregister_chrdev_region(dev, HWTEST_DEV_NUM); + HWTEST_major = -1; + } + g_state_flag = 0; + HWTEST_ERR_FUNC("fail \n"); + + return -1; +} + +static void HWTEST_exit (void) +{ + dev_t dev = MKDEV(HWTEST_major, 0); + cdev_del(&HWTEST_cdev); + unregister_chrdev_region(dev, HWTEST_DEV_NUM); + HWTEST_major = -1; + g_state_flag = 0; + g_sdio_init_count = 0; + HWTEST_INFO_FUNC("done\n"); +} + +MODULE_LICENSE("GPL"); +EXPORT_SYMBOL_GPL(g_read_card_info_bysdio); +EXPORT_SYMBOL_GPL(g_read_current_io_isready_from_sdio_card); +EXPORT_SYMBOL_GPL(g_read_function_blksize_from_sdio_card); +EXPORT_SYMBOL_GPL(g_read_int_from_sdio_card); + + +module_init(HWTEST_init); +module_exit(HWTEST_exit); + diff --git a/drivers/mtk_wcn_combo/common/linux/hw_sdio_client.c b/drivers/mtk_wcn_combo/common/linux/hw_sdio_client.c new file mode 100755 index 000000000000..ae123f8934de --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/hw_sdio_client.c @@ -0,0 +1,233 @@ + +#include +#include +#include +#include + +#include +#include +#include + +#include "hw_test.h" + + + +extern unsigned char** g_read_card_info_bysdio; +extern UINT8 g_read_current_io_isready_from_sdio_card; +extern UINT16 g_read_function_blksize_from_sdio_card; +extern UINT32 g_read_int_from_sdio_card; + +static const struct sdio_device_id hw_sdio_id_tbl[] = { + + /* 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) */ + {}, +}; + +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(sdio, hw_sdio_id_tbl); + +static int hw_sdio_probe ( + struct sdio_func *func, + const struct sdio_device_id *id + ); + +static void hw_sdio_remove ( + struct sdio_func *func + ); +INT32 read_card_info(struct sdio_func * func,UINT32 offset,PUINT32 pbuf,UINT32 len); + +static struct sdio_driver hw_sdio_client_drv = { + .name = "hw_sdio_client", /* MTK SDIO Client Driver */ + .id_table = hw_sdio_id_tbl, /* all supported struct sdio_device_id table */ + .probe = hw_sdio_probe, + .remove = hw_sdio_remove, +}; + +UINT8 read_sdio_card_register_by_cmd52(struct sdio_func * func) +{ + UINT8 val; + INT32 ret = -1; + + sdio_claim_host(func); + val = sdio_f0_readb(func,0x03,&ret); + sdio_release_host(func); + if(val == 0xff){ + HWTEST_INFO_FUNC("read CCCR I/O ready register by cmd52 fail!\n"); + return -1; + }else{ + HWTEST_INFO_FUNC("read CCCR I/O ready register by cmd52:0x%08x\n",val); + return val; + } +} + +UINT32 read_sdio_card_register_by_cmd53(struct sdio_func * func) +{ + UINT32 val; + INT32 ret = -1; + sdio_claim_host(func); + val = sdio_readl(func,0x0000,&ret); + sdio_release_host(func); + if(val == 0xffffffff){ + HWTEST_INFO_FUNC("read sdio register by cmd53 fail!\n"); + return -1; + }else{ + HWTEST_INFO_FUNC("read sdio register by cmd53:0x%08x\n",val); + return val; + } +} + +UINT16 read_sdio_card_cccr_register(struct sdio_func * func) +{ + UINT8 val1, val2; + INT32 ret = -1; + UINT16 result = 0; + + sdio_claim_host(func); + val1 = sdio_f0_readb(func,0x110,&ret); + sdio_release_host(func); + if(val1 == 0xff){ + HWTEST_INFO_FUNC("read sdio cccr register fail!\n"); + return -1; + }else{ + HWTEST_INFO_FUNC("read current function blksize_first byte:0x%08x\n",val1); + } + + sdio_claim_host(func); + val2 = sdio_f0_readb(func,0x111,&ret); + sdio_release_host(func); + if(val2 == 0xff){ + HWTEST_INFO_FUNC("read sdio cccr register fail!\n"); + return -1; + }else{ + HWTEST_INFO_FUNC("read current function blksize_second byte:0x%08x\n",val2); + } + result = val2 << 8; + result |= val1; + return result; +} + +static int hw_sdio_probe (struct sdio_func *func,const struct sdio_device_id *id) +{ + int i = 0; + char buf[128]; + + HWTEST_INFO_FUNC("%s start \n",__FUNCTION__); + if(!func){ + HWTEST_INFO_FUNC("func pointer is null!\n"); + return -1; + } + + //4 <0> display debug information + HWTEST_INFO_FUNC("vendor(0x%x) device(0x%x) num(0x%x)\n", func->vendor, func->device, func->num); + for (i = 0;i < func->card->num_info;i++) { + HWTEST_INFO_FUNC("card->info[%d]: %s\n", i, func->card->info[i]); + } + g_read_card_info_bysdio = (char **)kmalloc((func->card->num_info) * sizeof(char*),GFP_KERNEL); + + + + for(i = 0; i < func->card->num_info;i++){ + + HWTEST_INFO_FUNC("card info str(%d) strlen = %d\n",i,strlen(func->card->info[i])); + + if(!g_read_card_info_bysdio[i]){ + HWTEST_INFO_FUNC("kmalloc buffer fail!\n"); + return -2; + } + if(0 != strlen(func->card->info[i])){ + g_read_card_info_bysdio[i] = kmalloc(strlen(func->card->info[i]) * sizeof(char),GFP_KERNEL); + strcpy(g_read_card_info_bysdio[i],func->card->info[i]); + HWTEST_INFO_FUNC("g_read_card_info_bysdio[%d] = %s\n",i,g_read_card_info_bysdio[i]); + } + else{ + g_read_card_info_bysdio[i] = kmalloc(128,GFP_KERNEL); + memset(g_read_card_info_bysdio[i],0,128); + } + } + + + sprintf(buf,"verdor is 0x%x,device is 0x%x,func number is 0x%x",func->vendor,func->device,func->num); + HWTEST_INFO_FUNC("buf = %s\n",buf); + for(i = 0; i < func->card->num_info;i++){ + if(!g_read_card_info_bysdio[i][0]){ + strcpy(g_read_card_info_bysdio[i],buf); + break; + } + } + + + sdio_claim_host(func); + sdio_enable_func(func); + sdio_release_host(func); + + sdio_claim_host(func); + sdio_set_block_size(func, 512); + sdio_release_host(func); + + g_read_current_io_isready_from_sdio_card = read_sdio_card_register_by_cmd52(func); + g_read_function_blksize_from_sdio_card = read_sdio_card_cccr_register(func); + g_read_int_from_sdio_card = read_sdio_card_register_by_cmd53(func); + + HWTEST_INFO_FUNC("%s end\n", __FUNCTION__); + return 0; +} + +static void hw_sdio_remove (struct sdio_func *func) +{ + int i = 0; + HWTEST_INFO_FUNC("%s start \n",__FUNCTION__); + + if(!func){ + HWTEST_INFO_FUNC("func pointer is null!\n"); + return; + } + + for(i = 0; i < func->card->num_info;i++){ + + if(g_read_card_info_bysdio[i]){ + kfree(g_read_card_info_bysdio[i]); + } + } + + kfree(g_read_card_info_bysdio); + + HWTEST_INFO_FUNC("%s:sdio func(0x%p) is removed successfully!\n", __FUNCTION__, func); + + HWTEST_INFO_FUNC("%s end\n", __FUNCTION__); +} + + +static int __init hw_sdio_init(void) +{ + int ret = 0; + + HWTEST_INFO_FUNC("%s start \n",__FUNCTION__); + + //register to mmc driver + ret = sdio_register_driver(&hw_sdio_client_drv); + + HWTEST_INFO_FUNC("sdio_register_driver() ret=%d\n", ret); + HWTEST_INFO_FUNC("%s end\n", __FUNCTION__); + + return ret; +} + +static void __exit hw_sdio_exit(void) +{ + int ret = 0; + + HWTEST_INFO_FUNC("%s start \n", __FUNCTION__); + + sdio_unregister_driver(&hw_sdio_client_drv); + + + HWTEST_INFO_FUNC("%s end\n", __FUNCTION__); + return; +} + +module_init(hw_sdio_init); +module_exit(hw_sdio_exit); + diff --git a/drivers/mtk_wcn_combo/common/linux/include/hif_sdio.h b/drivers/mtk_wcn_combo/common/linux/include/hif_sdio.h new file mode 100755 index 000000000000..0618d8e7cd17 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/include/hif_sdio.h @@ -0,0 +1,350 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* +** $Id: $ +*/ + +/*! \file "hif_sdio.h" + \brief + + +*/ + +/* +** $Log: $ + * + * 07 25 2010 george.kuo + * + * Move hif_sdio driver to linux directory. + * + * 07 23 2010 george.kuo + * + * Add MT6620 driver source tree + * , including char device driver (wmt, bt, gps), stp driver, interface driver (tty ldisc and hif_sdio), and bt hci driver. +** +** +*/ + +#ifndef _HIF_SDIO_H +#define _HIF_SDIO_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define HIF_SDIO_DEBUG (0) /* 0:trun off debug msg and assert, 1:trun off debug msg and assert */ +#define SDIO_TAG "[HIF-SDIO]" + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_linux.h" +#include "osal.h" +#include "wmt_exp.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CFG_CLIENT_COUNT (9) + +#define HIF_DEFAULT_BLK_SIZE (256) +#define HIF_DEFAULT_VENDOR (0x037A) + +#define HIF_SDIO_LOG_LOUD 4 +#define HIF_SDIO_LOG_DBG 3 +#define HIF_SDIO_LOG_INFO 2 +#define HIF_SDIO_LOG_WARN 1 +#define HIF_SDIO_LOG_ERR 0 + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* Function info provided by client driver */ +typedef struct _MTK_WCN_HIF_SDIO_FUNCINFO MTK_WCN_HIF_SDIO_FUNCINFO; + +/* Client context provided by hif_sdio driver for the following function call */ +typedef UINT32 MTK_WCN_HIF_SDIO_CLTCTX; + +/* Callback functions provided by client driver */ +typedef INT32 (*MTK_WCN_HIF_SDIO_PROBE)(MTK_WCN_HIF_SDIO_CLTCTX, const MTK_WCN_HIF_SDIO_FUNCINFO *); +typedef INT32 (*MTK_WCN_HIF_SDIO_REMOVE)(MTK_WCN_HIF_SDIO_CLTCTX); +typedef INT32 (*MTK_WCN_HIF_SDIO_IRQ)(MTK_WCN_HIF_SDIO_CLTCTX); + +/* Function info provided by client driver */ +struct _MTK_WCN_HIF_SDIO_FUNCINFO { + UINT16 manf_id; /* TPLMID_MANF: manufacturer ID */ + UINT16 card_id; /* TPLMID_CARD: card ID */ + UINT16 func_num; /* Function Number */ + UINT16 blk_sz; /* Function block size */ +}; + +/* Client info provided by client driver */ +typedef struct _MTK_WCN_HIF_SDIO_CLTINFO { + const MTK_WCN_HIF_SDIO_FUNCINFO *func_tbl; /* supported function info table */ + UINT32 func_tbl_size; /* supported function table info element number */ + MTK_WCN_HIF_SDIO_PROBE hif_clt_probe; /* callback function for probing */ + MTK_WCN_HIF_SDIO_REMOVE hif_clt_remove; /* callback function for removing */ + MTK_WCN_HIF_SDIO_IRQ hif_clt_irq; /* callback function for interrupt handling */ +} MTK_WCN_HIF_SDIO_CLTINFO; + +/* function info provided by registed function */ +typedef struct _MTK_WCN_HIF_SDIO_REGISTINFO { + const MTK_WCN_HIF_SDIO_CLTINFO *sdio_cltinfo; /* client's MTK_WCN_HIF_SDIO_CLTINFO pointer */ + const MTK_WCN_HIF_SDIO_FUNCINFO *func_info; /* supported function info pointer */ +} MTK_WCN_HIF_SDIO_REGISTINFO; + +/* Card info provided by probed function */ +typedef struct _MTK_WCN_HIF_SDIO_PROBEINFO { + struct sdio_func* func; /* probed sdio function pointer */ + void* private_data_p; /* clt's private data pointer */ + MTK_WCN_BOOL on_by_wmt; /* TRUE: on by wmt, FALSE: not on by wmt */ + /* added for sdio irq sync and mmc single_irq workaround */ + MTK_WCN_BOOL sdio_irq_enabled; /* TRUE: can handle sdio irq; FALSE: no sdio irq handling */ + INT8 clt_idx; /* registered function table info element number (initial value is -1) */ +} MTK_WCN_HIF_SDIO_PROBEINFO; + +/* work queue info needed by worker */ +typedef struct _MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO { + struct work_struct probe_work; /* work queue structure */ + MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p; /* MTK_WCN_HIF_SDIO_REGISTINFO pointer of the client */ + INT8 probe_idx; /* probed function table info element number (initial value is -1) */ +} MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO; + +/* global resource locks info of hif_sdio drv */ +typedef struct _MTK_WCN_HIF_SDIO_LOCKINFO { + spinlock_t probed_list_lock; /* spin lock for probed list */ + spinlock_t clt_list_lock; /* spin lock for client registed list */ +} MTK_WCN_HIF_SDIO_LOCKINFO; + +/* error code returned by hif_sdio driver (use NEGATIVE number) */ +typedef enum { + HIF_SDIO_ERR_SUCCESS = 0, + HIF_SDIO_ERR_FAIL = HIF_SDIO_ERR_SUCCESS - 1, /* generic error */ + HIF_SDIO_ERR_INVALID_PARAM = HIF_SDIO_ERR_FAIL - 1, + HIF_SDIO_ERR_DUPLICATED = HIF_SDIO_ERR_INVALID_PARAM - 1, + HIF_SDIO_ERR_UNSUP_MANF_ID = HIF_SDIO_ERR_DUPLICATED - 1, + HIF_SDIO_ERR_UNSUP_CARD_ID = HIF_SDIO_ERR_UNSUP_MANF_ID - 1, + HIF_SDIO_ERR_INVALID_FUNC_NUM = HIF_SDIO_ERR_UNSUP_CARD_ID - 1, + HIF_SDIO_ERR_INVALID_BLK_SZ = HIF_SDIO_ERR_INVALID_FUNC_NUM - 1, + HIF_SDIO_ERR_NOT_PROBED = HIF_SDIO_ERR_INVALID_BLK_SZ - 1, + HIF_SDIO_ERR_ALRDY_ON = HIF_SDIO_ERR_NOT_PROBED -1, + HIF_SDIO_ERR_ALRDY_OFF = HIF_SDIO_ERR_ALRDY_ON -1, + HIF_SDIO_ERR_CLT_NOT_REG = HIF_SDIO_ERR_ALRDY_OFF - 1, +} MTK_WCN_HIF_SDIO_ERR ; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + + + +/*! + * \brief A macro used to describe an SDIO function + * + * Fill an MTK_WCN_HIF_SDIO_FUNCINFO structure with function-specific information + * + * \param manf the 16 bit manufacturer id + * \param card the 16 bit card id + * \param func the 16 bit function number + * \param b_sz the 16 bit function block size + */ +#define MTK_WCN_HIF_SDIO_FUNC(manf, card, func, b_sz) \ + .manf_id = (manf), .card_id = (card), .func_num = (func), .blk_sz = (b_sz) + +#define HIF_SDIO_LOUD_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_LOUD) { printk(KERN_INFO SDIO_TAG"[L]%s:" fmt, __FUNCTION__ ,##arg);} +#define HIF_SDIO_DBG_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_DBG) { printk(KERN_INFO SDIO_TAG"[D]%s:" fmt, __FUNCTION__ ,##arg);} +#define HIF_SDIO_INFO_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_INFO) { printk(KERN_INFO SDIO_TAG"[I]%s:" fmt, __FUNCTION__ ,##arg);} +#define HIF_SDIO_WARN_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_WARN) { printk(KERN_WARNING SDIO_TAG"[W]%s(%d):" fmt, __FUNCTION__ , __LINE__, ##arg);} +#define HIF_SDIO_ERR_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_ERR) { printk(KERN_WARNING SDIO_TAG"[E]%s(%d):" fmt, __FUNCTION__ , __LINE__, ##arg);} + +/*! + * \brief ASSERT function definition. + * + */ +#if HIF_SDIO_DEBUG +#define HIF_SDIO_ASSERT(expr) if ( !(expr) ) { \ + printk("assertion failed! %s[%d]: %s\n",\ + __FUNCTION__, __LINE__, #expr); \ + BUG_ON( !(expr) );\ + } +#else +#define HIF_SDIO_ASSERT(expr) do {} while(0) +#endif + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/*! + * \brief MTK hif sdio client registration function + * + * Client uses this function to do hif sdio registration + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 error code + */ +extern INT32 mtk_wcn_hif_sdio_client_reg ( + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo + ); + +extern INT32 mtk_wcn_hif_sdio_client_unreg ( + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo + ); + +extern INT32 mtk_wcn_hif_sdio_readb ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT8 pvb + ); + +extern INT32 mtk_wcn_hif_sdio_writeb ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + UINT8 vb + ); + +extern INT32 mtk_wcn_hif_sdio_readl ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pvl + ); + +extern INT32 mtk_wcn_hif_sdio_writel ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + UINT32 vl + ); + +extern INT32 mtk_wcn_hif_sdio_read_buf ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pbuf, + UINT32 len + ); + +extern INT32 mtk_wcn_hif_sdio_write_buf ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pbuf, + UINT32 len + ); + +extern void mtk_wcn_hif_sdio_set_drvdata( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + void* private_data_p + ); + +extern void* mtk_wcn_hif_sdio_get_drvdata( + MTK_WCN_HIF_SDIO_CLTCTX ctx + ); + +extern INT32 mtk_wcn_hif_sdio_wmt_control( + WMT_SDIO_FUNC_TYPE func_type, + MTK_WCN_BOOL is_on + ); + +extern void mtk_wcn_hif_sdio_get_dev( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + struct device **dev + ); + +extern void mtk_wcn_hif_sdio_enable_irq( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + MTK_WCN_BOOL enable + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_SDIO_H */ + + diff --git a/drivers/mtk_wcn_combo/common/linux/include/hw_test.h b/drivers/mtk_wcn_combo/common/linux/include/hw_test.h new file mode 100755 index 000000000000..3068ea19c4dc --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/include/hw_test.h @@ -0,0 +1,146 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file hw_test.h + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +#ifndef _HW_TEST_H +#define _HW_TEST_H + +/******************************************************************************* +* G L O B A L F L A G S +******************************************************************************** +*/ + + +static unsigned int g_state_flag = 0;//power on and power off +static unsigned int g_sdio_init_count = 0;//if it is the 1st init sdio card + +//extern unsigned char* g_read_card_info_bysdio[8]; +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define HWTEST_DRIVER_NAME "mtk_hw_test" + + +/* debug information */ +#define PFX "[HWTEST]" +#define DBG_NAME "[hw_test]" +#define HWTEST_LOG_LOUD 4 +#define HWTEST_LOG_DBG 3 +#define HWTEST_LOG_INFO 2 +#define HWTEST_LOG_WARN 1 +#define HWTEST_LOG_ERR 0 + +static unsigned int gHWDbgLvl = HWTEST_LOG_INFO; + +#define HWTEST_IOCTL_MAGIC 0xc4 + +#define HWTEST_IOCTL_POWER_ON _IO(HWTEST_IOCTL_MAGIC,0) +#define HWTEST_IOCTL_POWER_OFF _IO(HWTEST_IOCTL_MAGIC,1) +#define HWTEST_IOCTL_CHIP_RESET _IO(HWTEST_IOCTL_MAGIC,2) +#define HWTEST_IOCTL_SDIO_INIT _IO(HWTEST_IOCTL_MAGIC,3) +#define HWTEST_IOCTL_SDIO_REMOVE _IO(HWTEST_IOCTL_MAGIC,4) +#define HWTEST_IOCTL_SDIO_READ_IOISREADY _IOR(HWTEST_IOCTL_MAGIC,5,UINT8) +#define HWTEST_IOCTL_SDIO_READ_BLKSIZE _IOR(HWTEST_IOCTL_MAGIC,6,UINT16) +#define HWTEST_IOCTL_SDIO_READ_INT _IOR(HWTEST_IOCTL_MAGIC,7,UINT32) + + + + + +/******************************************************************************* +* D A T A T Y P E S +********************************************************************************/ +/* Type definition for signed integers */ +typedef signed int INT32, *PINT32; +typedef signed char INT8, *PINT8; +typedef signed short INT16, *PINT16; +/* Type definition for unsigned integers */ +typedef unsigned int UINT32, *PUINT32; +typedef unsigned char UINT8, *PUINT8; +typedef unsigned short UINT16,*PUINT16; + +typedef enum{ + HWTEST_POWER_ON = 0, + HWTEST_POWER_OFF = 1, + HWTEST_HW_REST = 2, + HWTEST_SDIO_INIT = 3, + HWTEST_CMD_MAX +}HWTEST_CMD; + +typedef enum _HWTEST_CHIPVERSION{ + HWVER_MT6620_E1 = 0x0, + HWVER_MT6620_E2 = 0x1, + HWVER_MT6620_E3 = 0x2, + HWVER_MT6620_E4 = 0x3, + HWVER_MT6620_E5 = 0x4, + HWVER_MT6620_E6 = 0x5, + HWVER_MT6620_MAX, + HWVER_INVALID = 0xff +} ENUM_HWTEST_CHIPVERSION_T; + +/* bit field offset definition */ +typedef enum { + HWTEST_STAT_PWRON = 0, /* is powered on */ + HWTEST_STAT_PWROFF = 1, + HWTEST_STAT_SDIO1_ON = 2, /* is SDIO1 on */ + HWTEST_STAT_SDIO2_ON = 3, /* is SDIO2 on */ + HWTEST_STAT_MAX +} HWTEST_STAT; + + +/* FIXME: apply KERN_* definition? */ +#define HWTEST_LOUD_FUNC(fmt, arg...) if (gHWDbgLvl >= HWTEST_LOG_LOUD) { printk(DBG_NAME"%s:" fmt, __FUNCTION__ ,##arg);} +#define HWTEST_DBG_FUNC(fmt, arg...) if (gHWDbgLvl >= HWTEST_LOG_DBG) { printk(DBG_NAME "%s:" fmt, __FUNCTION__ ,##arg);} +#define HWTEST_INFO_FUNC(fmt, arg...) if (gHWDbgLvl >= HWTEST_LOG_INFO) { printk(DBG_NAME "%s:" fmt, __FUNCTION__ ,##arg);} +#define HWTEST_WARN_FUNC(fmt, arg...) if (gHWDbgLvl >= HWTEST_LOG_WARN) { printk(DBG_NAME "%s:" fmt, __FUNCTION__ ,##arg);} +#define HWTEST_ERR_FUNC(fmt, arg...) if (gHWDbgLvl >= HWTEST_LOG_ERR) { printk(DBG_NAME "%s(%d):" fmt, __FUNCTION__ , __LINE__, ##arg);} +#define HWTEST_TRC_FUNC(f) if (gHWDbgLvl >= HWTEST_LOG_DBG) { printk(DBG_NAME "<%s> <%d>\n", __FUNCTION__, __LINE__);} +// for Ingenic +#define GPIO_PMU (32 * 3 + 3) /* GPD3*/ +#define GPIO_RST (32 * 3 + 0) /* GPD0 */ + +extern int sdio_card_detect(); +extern int sdio_card_remove(); +// end for Ingenic + +#endif /* _HW_TETS_H */ + diff --git a/drivers/mtk_wcn_combo/common/linux/include/mtk_wcn_cmb_stub.h b/drivers/mtk_wcn_combo/common/linux/include/mtk_wcn_cmb_stub.h new file mode 100755 index 000000000000..18682c0d69ec --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/include/mtk_wcn_cmb_stub.h @@ -0,0 +1,213 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _MTK_WCN_CMB_STUB_H_ +#define _MTK_WCN_CMB_STUB_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 { + 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_MAX = 4, +} 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; + +#if 1 /* copied from mt_combo.h */ +typedef enum { + COMBO_AUDIO_STATE_0 = 0, /* 0000: BT_PCM_OFF & FM analog (line in/out) */ + COMBO_AUDIO_STATE_1 = 1, /* 0001: BT_PCM_ON & FM analog (in/out) */ + COMBO_AUDIO_STATE_2 = 2, /* 0010: BT_PCM_OFF & FM digital (I2S) */ + COMBO_AUDIO_STATE_3 = 3, /* 0011: BT_PCM_ON & FM digital (I2S) (invalid in 73evb & 1.2 phone configuration) */ + COMBO_AUDIO_STATE_MAX = 4, +} COMBO_AUDIO_STATE; + +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_MAX, +} COMBO_IF; +#endif + +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 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; +} 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 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); + +#if 0 /* remove obsolete audio_ctrl APIs. Use stub_aif_ctrl()! */ +/* [GeorgeKuo] Stub functions for other kernel built-in modules to call. + * Keep them unchanged temporarily. Move mt_combo functions to mtk_wcn_combo. + */ +extern int mtk_wcn_cmb_stub_audio_ctrl_ex(COMBO_AUDIO_STATE state, u32 clt_ctrl); +static inline int mtk_wcn_cmb_stub_audio_ctrl(COMBO_AUDIO_STATE state) { + return mtk_wcn_cmb_stub_audio_ctrl_ex(state, 1); +} +#endif + +/* 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 mt_combo_plt_enter_deep_idle(COMBO_IF src); +extern int mt_combo_plt_exit_deep_idle(COMBO_IF src); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _MTK_WCN_CMB_STUB_H_ */ + diff --git a/drivers/mtk_wcn_combo/common/linux/include/osal_linux.h b/drivers/mtk_wcn_combo/common/linux/include/osal_linux.h new file mode 100755 index 000000000000..7d52fc6f7a8c --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/include/osal_linux.h @@ -0,0 +1,120 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#ifndef _OSAL_LINUX_H_ +#define _OSAL_LINUX_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WMT_PLAT_ALPS +#include +#endif +#include +#include +#include + + +#endif diff --git a/drivers/mtk_wcn_combo/common/linux/include/osal_typedef.h b/drivers/mtk_wcn_combo/common/linux/include/osal_typedef.h new file mode 100755 index 000000000000..55b0b40451ef --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/include/osal_typedef.h @@ -0,0 +1,98 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2011. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \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_ + +typedef void VOID; +typedef void *PVOID; + +typedef char CHAR; +typedef char *PCHAR; +typedef signed char INT8; +typedef signed char *PINT8; +typedef unsigned char UINT8; +typedef unsigned char *PUINT8; +typedef unsigned char UCHAR; +typedef unsigned char *PUCHAR; + +typedef signed short INT16; +typedef signed short *PINT16; +typedef unsigned short UINT16; +typedef unsigned short *PUINT16; + +typedef signed long LONG; +typedef signed long *PLONG; + +typedef signed int INT32; +typedef signed int *PINT32; +typedef unsigned int UINT32; +typedef unsigned int *PUINT32; + +typedef unsigned long ULONG; +typedef unsigned long *PULONG; + +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 + +#ifndef NULL +#define NULL ((VOID *)0) +#endif + +typedef VOID *TIMER_REF; +typedef VOID *SPINLOCK_REF; +typedef VOID *MUTEX_REF; +typedef VOID *WAITQUEUE_REF; +typedef VOID *FIRMWARE_REF; +typedef VOID *PROCENTRY_REF; +typedef VOID *COMPLETION_REF; +typedef VOID *THREAD_REF; +typedef VOID *WAKELOCK_REF; + + +#endif /*_OSAL_TYPEDEF_H_*/ + diff --git a/drivers/mtk_wcn_combo/common/linux/include/wmt_dev.h b/drivers/mtk_wcn_combo/common/linux/include/wmt_dev.h new file mode 100755 index 000000000000..ff753bf90150 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/include/wmt_dev.h @@ -0,0 +1,50 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#ifndef _WMT_DEV_H_ +#define _WMT_DEV_H_ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "osal.h" + +extern INT32 wmt_dev_patch_get (UCHAR *pPatchName, OSAL_FIRMWARE **ppPatch,INT32 padSzBuf); +extern INT32 wmt_dev_patch_put(OSAL_FIRMWARE **ppPatch); + +#endif /*_WMT_DEV_H_*/ + diff --git a/drivers/mtk_wcn_combo/common/linux/osal.c b/drivers/mtk_wcn_combo/common/linux/osal.c new file mode 100755 index 000000000000..ef6d7051213d --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/osal.c @@ -0,0 +1,1567 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* 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_linux.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 +******************************************************************************** +*/ + + + + + +/******************************************************************************* +* 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*/ +UINT32 osal_strlen(const char *str) +{ + return strlen(str); +} + +INT32 osal_strcmp(const char *dst, const char *src) +{ + return strcmp(dst, src); +} + +INT32 osal_strncmp(const char *dst, const char *src, UINT32 len) +{ + return strncmp(dst, src, len); +} + +char * osal_strcpy(char *dst, const char *src) +{ + return strcpy(dst, src); +} + +char * osal_strncpy(char *dst, const char *src, UINT32 len) +{ + return strncpy(dst, src, len); +} + + +char * osal_strcat(char *dst, const char *src) +{ + return strcat(dst, src); +} + +char * osal_strncat(char *dst, const char *src, UINT32 len) +{ + return strncat(dst, src, len); +} + +char * osal_strchr(const char *str, UINT8 c) +{ + return strchr(str, c); +} + + +char * osal_strsep(char **str, const char *c) +{ + return strsep(str, c); +} + + +LONG osal_strtol(const char *str, char **c, UINT32 adecimal) +{ + return simple_strtol(str, c, adecimal); +} + +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);*/// TODO: [FixMe][GeorgeKuo] BUG? + iRet = vsnprintf(buf, len, fmt, args); + va_end(args); + + return iRet; +} + +INT32 osal_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); + + printk("%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); + + printk(KERN_DEBUG "%s",tempString); + + return 0; +} + +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); + + printk(KERN_ERR "%s",tempString); + + return 0; +} + +INT32 osal_info_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); + + printk(KERN_INFO "%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); + + printk(KERN_WARNING "%s",tempString); + + return 0; +} + +INT32 osal_loud_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); + + printk(KERN_DEBUG "%s",tempString); + + return 0; +} +/* +EXPORT_SYMBOL(osal_dbg_print); +EXPORT_SYMBOL(osal_err_print); +EXPORT_SYMBOL(osal_info_print); +EXPORT_SYMBOL(osal_warn_print); +EXPORT_SYMBOL(osal_loud_print); +*/ + +INT32 osal_dbg_assert(INT32 expr, const char *file, INT32 line) +{ + if (!expr){ + printk("%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); + printk("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); +#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; +} + +VOID* osal_malloc(UINT32 size) +{ + return vmalloc(size); +} + + +VOID osal_vfree(const VOID *dst) +{ + vfree(dst); +} + +VOID osal_kfree(const VOID *dst) +{ + kfree(dst); +} + +VOID* osal_memset(VOID *buf, INT32 i, UINT32 len) +{ + return memset(buf, i, len); +} + + +VOID* osal_memcpy(VOID *dst, const VOID *src, UINT32 len) +{ + return memcpy(dst, src, len); +} + + +INT32 osal_memcmp(const VOID *buf1, const VOID *buf2, UINT32 len) +{ + return memcmp(buf1, buf2, len); +} + +VOID* osal_kzalloc_sleep(UINT32 size) +{ + return kzalloc(size,GFP_KERNEL); +} + +VOID* osal_kzalloc_unsleep(UINT32 size) +{ + return kzalloc(size,GFP_ATOMIC); +} + + +/* + *OSAL layer Thread Opeartion releated APIs + * + * +*/ +INT32 +osal_thread_create ( + P_OSAL_THREAD pThread + ) +{ + //pThread->pThread = NULL; /* [FIXME] why? */ + if(pThread) + { + pThread->pThread = (struct task_struct *)kthread_create(pThread->pThreadFunc, + pThread->pThreadData, + pThread->threadName); + if (NULL == pThread->pThread) { + return -1; + } + return 0; + } + else + { + return -2; + } +} +INT32 +osal_thread_run ( + P_OSAL_THREAD pThread + ) +{ + if (pThread->pThread) { + wake_up_process((struct task_struct *)pThread->pThread); + return 0; + } + else { + return -1; + } +} + +INT32 +osal_thread_stop ( + P_OSAL_THREAD pThread + ) +{ + INT32 iRet; + if ( (pThread) && (pThread->pThread) ) { + iRet = kthread_stop((struct task_struct *)pThread->pThread); + //pThread->pThread = NULL; + return iRet; + } + return -1; +} + + +INT32 +osal_thread_should_stop ( + P_OSAL_THREAD pThread + ) +{ + if ( (pThread) && (pThread->pThread) ) { + return kthread_should_stop(); + } + else { + return 1; + } +} + + +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((*(wait_queue_head_t *)pEvent->pWaitQueue), + (/*!RB_EMPTY(&pDevWmt->rActiveOpQ) ||*/ osal_thread_should_stop(pThread) || (*pChecker)(pThread))); + } + return -1; +} + +INT32 +osal_thread_destroy ( + P_OSAL_THREAD pThread + ) +{ + if (pThread && (pThread->pThread)) { + kthread_stop((struct task_struct *)pThread->pThread); + pThread->pThread = NULL; + } + return 0; +} + +/* + *OSAL layer Signal Opeartion releated APIs + *initialization + *wait for signal + *wait for signal timerout + *raise signal + *destroy a signal + * +*/ + +INT32 +osal_signal_init ( + P_OSAL_SIGNAL pSignal + ) +{ + if (pSignal) { + //pSignal->pComp = NULL; + pSignal->pComp = kzalloc(sizeof(struct completion),GFP_KERNEL); + if (!pSignal->pComp){ + osal_info_print("%s:completion memory allocate fail!\n",__func__); + return -1; + } + init_completion((struct completion *)pSignal->pComp); + return 0; + } + else { + return -2; + } +} + +INT32 +osal_wait_for_signal ( + P_OSAL_SIGNAL pSignal + ) +{ + if (pSignal) { + wait_for_completion_interruptible((struct completion *)pSignal->pComp); + return 0; + } + else { + return -1; + } +} + +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((struct completion *)pSignal->pComp, msecs_to_jiffies(pSignal->timeoutValue)); +} + +INT32 +osal_raise_signal ( + P_OSAL_SIGNAL pSignal + ) +{ + // TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! + if(pSignal && pSignal->pComp){ + complete((struct completion *)pSignal->pComp); + return 0; + } + else + { + return -1; + } +} + +INT32 +osal_signal_deinit ( + P_OSAL_SIGNAL pSignal + ) +{ + // TODO:[FixMe][GeorgeKuo]: DO sanity check here!!! + if(pSignal) + { + if (pSignal->pComp){ + kfree(pSignal->pComp); + pSignal->pComp = NULL; + } + pSignal->timeoutValue = 0; + return 0; + } + else + { + return -1; + } +} + + +/* + *OSAL layer Event Opeartion releated APIs + *initialization + *wait for signal + *wait for signal timerout + *raise signal + *destroy a signal + * +*/ + +INT32 osal_event_init ( + P_OSAL_EVENT pEvent + ) +{ + //pEvent->pWaitQueue = NULL; /* [FIXME] why? */ + pEvent->pWaitQueue = kzalloc(sizeof(wait_queue_head_t),GFP_KERNEL); + if (!pEvent->pWaitQueue){ + osal_info_print("%s:waitqueue memory allocate fail!\n",__func__); + return -1; + } + init_waitqueue_head((wait_queue_head_t *)pEvent->pWaitQueue); + + return 0; +} + +INT32 osal_wait_for_event( + P_OSAL_EVENT pEvent, + INT32 (*condition)(PVOID), + void *cond_pa + ) +{ + return wait_event_interruptible((*(wait_queue_head_t *)pEvent->pWaitQueue), condition(cond_pa)); +} + +INT32 osal_wait_for_event_timeout( + P_OSAL_EVENT pEvent, + INT32 (*condition)(PVOID), + void *cond_pa + ) +{ + return wait_event_interruptible_timeout((*(wait_queue_head_t *)pEvent->pWaitQueue), condition(cond_pa), msecs_to_jiffies(pEvent->timeoutValue)); +} + +INT32 osal_trigger_event( + P_OSAL_EVENT pEvent + ) +{ + INT32 ret = 0; + wake_up_interruptible((wait_queue_head_t *)pEvent->pWaitQueue); + return ret; +} + +INT32 +osal_event_deinit ( + P_OSAL_EVENT pEvent + ) +{ + if (pEvent->pWaitQueue){ + kfree(pEvent->pWaitQueue); + pEvent->pWaitQueue = NULL; + } + return 0; +} + +LONG osal_wait_for_event_bit_set(P_OSAL_EVENT pEvent, PULONG pState, UINT32 bitOffset) +{ + UINT32 ms = pEvent->timeoutValue; + if (ms != 0) + { + return wait_event_interruptible_timeout((*(wait_queue_head_t *)pEvent->pWaitQueue), test_bit(bitOffset, pState), msecs_to_jiffies(ms)); + } + else + { + return wait_event_interruptible((*(wait_queue_head_t *)pEvent->pWaitQueue), test_bit(bitOffset, pState)); + } + +} + +LONG osal_wait_for_event_bit_clr(P_OSAL_EVENT pEvent, PULONG pState, UINT32 bitOffset) +{ + UINT32 ms = pEvent->timeoutValue; + if (ms != 0) + { + return wait_event_interruptible_timeout((*(wait_queue_head_t *)pEvent->pWaitQueue), !test_bit(bitOffset, pState), msecs_to_jiffies(ms)); + } + else + { + return wait_event_interruptible((*(wait_queue_head_t *)pEvent->pWaitQueue), !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 + +INT32 osal_bit_op_lock(P_OSAL_UNSLEEPABLE_LOCK pLock) +{ + + return 0; +} + +INT32 osal_bit_op_unlock(P_OSAL_UNSLEEPABLE_LOCK pLock) +{ + + return 0; +} +#endif +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; +} + +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; +} + +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; +} + +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; + +} + +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 = NULL; + pTimer->pTimer = kzalloc(sizeof(struct timer_list),GFP_KERNEL); + if (!pTimer->pTimer){ + osal_info_print("%s:timer memory allocate fail!\n",__func__); + return -1; + } + timer = (struct timer_list *)pTimer->pTimer; + init_timer(timer); + timer->function = pTimer->timeoutHandler; + timer->data = (unsigned long)pTimer->timeroutHandlerData; + return 0; +} +INT32 osal_timer_start(P_OSAL_TIMER pTimer, UINT32 ms) +{ + + struct timer_list *timer = (struct timer_list *)pTimer->pTimer; + timer->expires = jiffies + msecs_to_jiffies(ms); + add_timer(timer); + return 0; +} + +INT32 osal_timer_stop(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = (struct timer_list *)pTimer->pTimer; + del_timer(timer); + return 0; +} + +INT32 osal_timer_stop_sync(P_OSAL_TIMER pTimer) +{ + struct timer_list *timer = (struct timer_list *)pTimer->pTimer; + del_timer_sync(timer); + return 0; +} + +INT32 osal_timer_modify(P_OSAL_TIMER pTimer, UINT32 ms) +{ + mod_timer((struct timer_list *)pTimer->pTimer, jiffies + msecs_to_jiffies(ms)); + return 0; +} + +INT32 osal_timer_delete(P_OSAL_TIMER pTimer) +{ + if (pTimer->pTimer){ + kfree(pTimer->pTimer); + pTimer->pTimer = NULL; + } + return 0; +} + +INT32 _osal_fifo_init(OSAL_FIFO *pFifo, UINT8 *buf, UINT32 size) +{ + struct kfifo *fifo = NULL; + INT32 ret = -1; + + if (!pFifo || pFifo->pFifoBody) + { + printk (KERN_ERR "pFifo must be !NULL, pFifo->pFifoBody must be NULL\n"); + printk (KERN_ERR "pFifo(0x%p), pFifo->pFifoBody(0x%p)\n", pFifo, pFifo->pFifoBody); + return -1; + } + + pFifo->fifoSpinlock = NULL; + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + pFifo->fifoSpinlock = kzalloc(sizeof(spinlock_t),GFP_ATOMIC); + if (!pFifo->fifoSpinlock){ + osal_info_print("%s:fifo spinlock allocate memory fail!",__func__); + return -2; + } + spin_lock_init((spinlock_t *)pFifo->fifoSpinlock); + fifo = kfifo_alloc(size, /*GFP_KERNEL*/GFP_ATOMIC, (spinlock_t *)pFifo->fifoSpinlock); + if (NULL == fifo) + { + ret = -3; + } + else + { + ret = 0; + } + #else + 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; + } + } + #endif + pFifo->pFifoBody = fifo; + return (ret < 0) ? (-1) : (0); +} + +INT32 _osal_fifo_deinit(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + + if (!pFifo || !pFifo->pFifoBody) + { + printk("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + { + kfifo_free(fifo); + } + + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + if (pFifo->fifoSpinlock) + { + kfree(pFifo->fifoSpinlock); + pFifo->fifoSpinlock = NULL; + } + #endif + return 0; +} + +INT32 _osal_fifo_size(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) + { + printk("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + ret = fifo->size; + #else + ret = kfifo_size(fifo); + #endif + + } + + 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) + { + printk("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + ret = fifo->size - kfifo_len(fifo); + #else + ret = kfifo_avail(fifo); + #endif + } + + 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) + { + printk("%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) + { + printk("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + ret = (fifo->in == fifo->out); + #else + ret = kfifo_is_empty(fifo); + #endif + } + + return ret; +} + +INT32 _osal_fifo_is_full(OSAL_FIFO *pFifo) +{ + struct kfifo *fifo = NULL; + INT32 ret = 0; + + if (!pFifo || !pFifo->pFifoBody) + { + printk("%s:pFifo = NULL or pFifo->pFifoBody = NULL, error\n", __func__); + return -1; + } + + fifo = (struct kfifo *)pFifo->pFifoBody; + + if (fifo) + { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + ret = (fifo->size == _osal_fifo_len(pFifo)); + #else + ret = kfifo_is_full(fifo); + #endif + } + + 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) + { + printk("%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))) + { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + ret = kfifo_put(fifo, buf, len); + #else + ret = kfifo_in(fifo, buf, len); + #endif + + } + else + { + printk("%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) + { + printk("%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))) + { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + ret = kfifo_get(fifo, buf, len); + #else + ret = kfifo_out(fifo, buf, len); + #endif + } + else + { + printk("%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) + { + printk("%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) + { + printk("%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) + { + printk("%s:Becasue 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 + { + printk("%s:pFifo = NULL, error\n", __func__); + } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + +#else + + if (pFifo->pFifoBody) + { + kfree(pFifo->pFifoBody); + } +#endif +} + +INT32 osal_fifo_reset(P_OSAL_FIFO pFifo) +{ + if (pFifo) + { + return pFifo->FifoReset(pFifo); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return -1; + } +} + +UINT32 osal_fifo_in(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) +{ + if (pFifo) + { + return pFifo->FifoDataIn(pFifo, buffer, size); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return 0; + } +} + +UINT32 osal_fifo_out(P_OSAL_FIFO pFifo, PUINT8 buffer, UINT32 size) +{ + if (pFifo) + { + return pFifo->FifoDataOut(pFifo, buffer, size); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return 0; + } +} + +UINT32 osal_fifo_len(P_OSAL_FIFO pFifo) +{ + if (pFifo) + { + return pFifo->FifoLen(pFifo); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return 0; + } +} + +UINT32 osal_fifo_sz(P_OSAL_FIFO pFifo) +{ + if (pFifo) + { + return pFifo->FifoSz(pFifo); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return 0; + } +} + +UINT32 osal_fifo_avail(P_OSAL_FIFO pFifo) +{ + if (pFifo) + { + return pFifo->FifoAvailSz(pFifo); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return 0; + } +} + +UINT32 osal_fifo_is_empty(P_OSAL_FIFO pFifo) +{ + if (pFifo) + { + return pFifo->FifoIsEmpty(pFifo); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return 0; + } +} + +UINT32 osal_fifo_is_full(P_OSAL_FIFO pFifo) +{ + if (pFifo) + { + return pFifo->FifoIsFull(pFifo); + } + else + { + printk("%s:pFifo = NULL, error\n", __func__); + return 0; + } +} + +INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + { + return -1; + } + else + { + pLock->pWakeLock = kzalloc(sizeof(struct wake_lock), GFP_KERNEL); + if (!pLock->pWakeLock) + { + osal_info_print("%s:wake lock memory allocate fail!\n",__func__); + return -2; + } + wake_lock_init((struct wake_lock *)pLock->pWakeLock, WAKE_LOCK_SUSPEND, pLock->name); + + return 0; + } +} + +INT32 osal_wake_lock_deinit(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + { + return -1; + } + else + { + wake_lock_destroy((struct wake_lock *)pLock->pWakeLock); + if (pLock->pWakeLock) + { + kfree(pLock->pWakeLock); + pLock->pWakeLock = NULL; + } + return 0; + } +} + +INT32 osal_wake_lock(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + { + return -1; + } + else + { + wake_lock((struct wake_lock *)pLock->pWakeLock); + + return 0; + } +} + + +INT32 osal_wake_unlock(P_OSAL_WAKE_LOCK pLock) +{ + if (!pLock) + { + return -1; + } + else + { + wake_unlock((struct wake_lock *)pLock->pWakeLock); + + return 0; + } +} + +INT32 osal_wake_lock_count(P_OSAL_WAKE_LOCK pLock) +{ + INT32 count = 0; + + if (!pLock) + { + return -1; + } + else + { + count = wake_lock_active((struct wake_lock *)pLock->pWakeLock); + return count; + } +} + +/* + *sleepable lock operations APIs + *init + *lock + *unlock + *destroy + * +*/ + +INT32 osal_unsleepable_lock_init (P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + /* sanity check on input parameter */ + if (!pUSL || pUSL->pLock) { + printk(KERN_WARNING "ERROR!!pUSL(0x%p)->pLock(0x%p)!\n", + pUSL, (pUSL) ? pUSL->pLock : 0x0); + return -1; + } + + pUSL->pLock = kzalloc(sizeof(spinlock_t),GFP_ATOMIC); + if (!pUSL->pLock){ + osal_info_print("%s:spinlock memory allocate fail!\n",__func__); + return -1; + } + + spin_lock_init((spinlock_t *)pUSL->pLock); + return 0; +} + +INT32 osal_lock_unsleepable_lock (P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + /* sanity check on input parameter */ + if (!pUSL || !pUSL->pLock) { + printk(KERN_WARNING "ERROR!!pUSL(0x%p)->pLock(0x%p)!\n", + pUSL, (pUSL) ? pUSL->pLock : 0x0); + return -1; + } + + spin_lock_irqsave((spinlock_t *)pUSL->pLock, pUSL->flag); + return 0; +} + +INT32 osal_unlock_unsleepable_lock (P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + /* sanity check on input parameter */ + if (!pUSL || !pUSL->pLock) { + printk(KERN_WARNING "ERROR!!pUSL(0x%p)->pLock(0x%p)!\n", + pUSL, (pUSL) ? pUSL->pLock : 0x0); + return -1; + } + + spin_unlock_irqrestore((spinlock_t *)pUSL->pLock, pUSL->flag); + return 0; +} + +extern INT32 osal_unsleepable_lock_deinit (P_OSAL_UNSLEEPABLE_LOCK pUSL) +{ + /* sanity check on input parameter */ + if (!pUSL || !pUSL->pLock) { + printk(KERN_WARNING "ERROR!!pUSL(0x%p)->pLock(0x%p)!\n", + pUSL, (pUSL) ? pUSL->pLock : 0x0); + return -1; + } + + if (pUSL->pLock){ + kfree(pUSL->pLock); + pUSL->pLock = NULL; + } + + return 0; +} + +/* + *unsleepable operations APIs + *init + *lock + *unlock + *destroy + + * +*/ + +INT32 osal_sleepable_lock_init (P_OSAL_SLEEPABLE_LOCK pSL) +{ + /* sanity check on input parameter */ + if (!pSL || pSL->pLock) { + printk(KERN_WARNING "ERROR!!pSL(0x%p)->pLock(0x%p)!\n", + pSL, (pSL) ? pSL->pLock : 0x0); + return -1; + } + + pSL->pLock = kzalloc(sizeof(struct mutex),GFP_KERNEL); + if (!pSL->pLock){ + osal_info_print("%s:mutex memory allocate fail!\n",__func__); + return -1; + } + + mutex_init ((struct mutex *)pSL->pLock); + return 0; +} + +INT32 osal_lock_sleepable_lock (P_OSAL_SLEEPABLE_LOCK pSL) +{ + /* sanity check on input parameter */ + if (!pSL || !pSL->pLock) { + printk(KERN_WARNING "ERROR!!pSL(0x%p)->pLock(0x%p)!\n", + pSL, (pSL) ? pSL->pLock : 0x0); + return -1; + } + + return mutex_lock_interruptible((struct mutex *)pSL->pLock); +} + +INT32 osal_unlock_sleepable_lock (P_OSAL_SLEEPABLE_LOCK pSL) +{ + /* sanity check on input parameter */ + if (!pSL || !pSL->pLock) { + printk(KERN_WARNING "ERROR!!pSL(0x%p)->pLock(0x%p)!\n", + pSL, (pSL) ? pSL->pLock : 0x0); + return -1; + } + + mutex_unlock((struct mutex *)pSL->pLock); + return 0; +} + + +INT32 osal_sleepable_lock_deinit (P_OSAL_SLEEPABLE_LOCK pSL) +{ + /* sanity check on input parameter */ + if (!pSL || !pSL->pLock) { + printk(KERN_WARNING "ERROR!!pSL(0x%p)->pLock(0x%p)!\n", + pSL, (pSL) ? pSL->pLock : 0x0); + return -1; + } + + mutex_destroy ((struct mutex *)pSL->pLock); + + if (pSL->pLock){ + kfree(pSL->pLock); + pSL->pLock = NULL; + } + + return 0; +} + +INT32 osal_msleep(UINT32 ms) +{ + msleep(ms); + 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; + + printk("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)) printk("\n"); + printk("0x%02x ", buf[k]); + } + printk("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); + } +} + + diff --git a/drivers/mtk_wcn_combo/common/linux/stp_chrdev_bt.c b/drivers/mtk_wcn_combo/common/linux/stp_chrdev_bt.c new file mode 100755 index 000000000000..e7b6ddc50947 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/stp_chrdev_bt.c @@ -0,0 +1,527 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "stp_exp.h" +#include "wmt_exp.h" + +MODULE_LICENSE("Dual BSD/GPL"); + +#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_BT_HWVER 6 + +unsigned int gDbgLevel = BT_LOG_ERR;//BT_LOG_INFO; //Modify loglevel + +#define BT_DBG_FUNC(fmt, arg...) if(gDbgLevel >= BT_LOG_DBG){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define BT_INFO_FUNC(fmt, arg...) if(gDbgLevel >= BT_LOG_INFO){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define BT_WARN_FUNC(fmt, arg...) if(gDbgLevel >= BT_LOG_WARN){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define BT_ERR_FUNC(fmt, arg...) if(gDbgLevel >= BT_LOG_ERR){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define BT_TRC_FUNC(f) if(gDbgLevel >= BT_LOG_DBG){printk(PFX "<%s> <%d>\n", __FUNCTION__, __LINE__);} + +#define VERSION "1.0" +#define BT_NVRAM_CUSTOM_NAME "/data/BT_Addr" + +static int BT_devs = 1; /* device count */ +static int BT_major = BT_DEV_MAJOR; /* dynamic allocation */ +module_param(BT_major, uint, 0); +static struct cdev BT_cdev; + +static unsigned char i_buf[MTKSTP_BUFFER_SIZE]; // input buffer of read() +static unsigned char o_buf[MTKSTP_BUFFER_SIZE]; // output buffer of write() +static struct semaphore wr_mtx, rd_mtx; +static wait_queue_head_t inq; /* read queues */ +static DECLARE_WAIT_QUEUE_HEAD(BT_wq); +static int flag = 0; +volatile int retflag = 0; + +unsigned char g_bt_bd_addr[10]={0x01,0x1a,0xfc,0x06,0x00,0x55,0x66,0x77,0x88,0x00}; +unsigned char g_nvram_btdata[8]; + +static int nvram_read(char *filename, char *buf, ssize_t len, int offset) +{ + struct file *fd; + //ssize_t ret; + 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)) { + BT_ERR_FUNC("failed to open!!\n"); + return -1; + } + do{ + if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) + { + BT_ERR_FUNC("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) { + BT_ERR_FUNC("[nvram_read] : failed to seek!!\n"); + break; + } + } else { + fd->f_pos = offset; + } + } + + retLen = fd->f_op->read(fd, + buf, + len, + &fd->f_pos); + + }while(false); + + filp_close(fd, NULL); + + set_fs(old_fs); + + return retLen; +} + + +int platform_load_nvram_data( char * filename, char * buf, int len) +{ + //int ret; + BT_INFO_FUNC("platform_load_nvram_data ++ BDADDR\n"); + + return nvram_read( filename, buf, len, 0); +} + +static void bt_cdev_rst_cb( + ENUM_WMTDRV_TYPE_T src, + ENUM_WMTDRV_TYPE_T dst, + ENUM_WMTMSG_TYPE_T type, + void *buf, + unsigned int sz){ + + /* + To handle reset procedure please + */ + ENUM_WMTRSTMSG_TYPE_T rst_msg; + + BT_INFO_FUNC("sizeof(ENUM_WMTRSTMSG_TYPE_T) = %d\n", sizeof(ENUM_WMTRSTMSG_TYPE_T)); + if(sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)){ + memcpy((char *)&rst_msg, (char *)buf, sz); + BT_INFO_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 restart start!\n"); + retflag = 1; + wake_up_interruptible(&inq); + /*reset_start message handling*/ + + } else if(rst_msg == WMTRSTMSG_RESET_END){ + BT_INFO_FUNC("BT restart end!\n"); + retflag = 2; + wake_up_interruptible(&inq); + /*reset_end message handling*/ + } + } + } else { + /*message format invalid*/ + BT_INFO_FUNC("message format invalid!\n"); + } +} + +void BT_event_cb(void) +{ + BT_DBG_FUNC("BT_event_cb() \n"); + + flag = 1; + wake_up(&BT_wq); + + /* finally, awake any reader */ + wake_up_interruptible(&inq); /* blocked in read() and select() */ + + return; +} + +unsigned int BT_poll(struct file *filp, poll_table *wait) +{ + unsigned int 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); + + /* empty let select sleep */ + if((!mtk_wcn_stp_is_rxqueue_empty(BT_TASK_INDX)) || retflag) + { + mask |= POLLIN | POLLRDNORM; /* readable */ + } + } + else + { + mask |= POLLIN | POLLRDNORM; /* readable */ + } + + /* do we need condition? */ + 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) +{ + int retval = 0; + int written = 0; + down(&wr_mtx); + + BT_DBG_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos); + if(retflag) + { + if (retflag == 1) //reset start + { + retval = -88; + BT_INFO_FUNC("MT6620 reset Write: start\n"); + } + else if (retflag == 2) // reset end + { + retval = -99; + BT_INFO_FUNC("MT6620 reset Write: end\n"); + } + goto OUT; + } + + if (count > 0) + { + int copy_size = (count < MTKSTP_BUFFER_SIZE) ? count : MTKSTP_BUFFER_SIZE; + if (copy_from_user(&o_buf[0], &buf[0], copy_size)) + { + retval = -EFAULT; + goto OUT; + } + //printk("%02x ", val); + + written = mtk_wcn_stp_send_data(&o_buf[0], copy_size, BT_TASK_INDX); + if(0 == written) + { + retval = -ENOSPC; + /*no windowspace in STP is available, native process should not call BT_write with no delay at all*/ + BT_ERR_FUNC("target packet length:%d, write success length:%d, retval = %d.\n", count, written, retval); + } + else + { + retval = written; + } + + }else + { + retval = -EFAULT; + BT_ERR_FUNC("target packet length:%d 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) +{ + int retval = 0; + + down(&rd_mtx); + + BT_DBG_FUNC("BT_read(): count %d pos %lld\n", count, *f_pos); + if(retflag) + { + if (retflag == 1) //reset start + { + retval = -88; + BT_INFO_FUNC("MT6620 reset Read: start\n"); + } + else if (retflag == 2) // reset end + { + retval = -99; + BT_INFO_FUNC("MT6620 reset Read: end\n"); + } + goto OUT; + } + + if(count > MTKSTP_BUFFER_SIZE) + { + count = MTKSTP_BUFFER_SIZE; + } + 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("BT_read(): wait_event 1\n"); + wait_event(BT_wq, flag != 0); + BT_DBG_FUNC("BT_read(): wait_event 2\n"); + flag = 0; + retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX); + BT_DBG_FUNC("BT_read(): mtk_wcn_stp_receive_data() = %d\n", retval); + } + + // we got something from STP driver + if (copy_to_user(buf, i_buf, retval)) + { + retval = -EFAULT; + goto OUT; + } + +OUT: + up(&rd_mtx); + BT_DBG_FUNC("BT_read(): retval = %d\n", 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) +{ + int retval = 0; + + + ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; + BT_DBG_FUNC("BT_ioctl(): cmd (%d)\n", cmd); + + switch(cmd) + { +#if 0 + case 0: // enable/disable STP + /* George: STP is controlled by WMT only */ + /* mtk_wcn_stp_enable(arg); */ + break; +#endif + case 1: // send raw data + BT_DBG_FUNC("BT_ioctl(): disable raw data from BT dev \n"); + retval = -EINVAL; + break; + case COMBO_IOC_BT_HWVER: + /*get combo hw version*/ + hw_ver_sym = mtk_wcn_wmt_hwver_get(); + + BT_INFO_FUNC("BT_ioctl(): get hw version = %d, sizeof(hw_ver_sym) = %d\n", hw_ver_sym, sizeof(hw_ver_sym)); + if(copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))){ + retval = -EFAULT; + } + break; + default: + retval = -EFAULT; + BT_DBG_FUNC("BT_ioctl(): unknown cmd (%d)\n", cmd); + break; + } + + return retval; +} + +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 + ); + +#if 1 /* GeorgeKuo: turn on function before check stp ready */ + /* 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; + }else{ + retflag = 0; + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb); + BT_INFO_FUNC("WMT register BT rst cb!\n"); + } +#endif + + if (mtk_wcn_stp_is_ready()) { +#if 0 /* GeorgeKuo: turn on function before check stp ready */ + /* 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; + } +#endif + mtk_wcn_stp_set_bluez(0); + + BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n"); + BT_INFO_FUNC("WMT turn on BT OK!\n"); + BT_INFO_FUNC("STP is ready!\n"); + platform_load_nvram_data(BT_NVRAM_CUSTOM_NAME, + (char *)&g_nvram_btdata, sizeof(g_nvram_btdata)); + + BT_INFO_FUNC("Read NVRAM : BD address %02x%02x%02x%02x%02x%02x Cap 0x%02x Codec 0x%02x\n", + g_nvram_btdata[0], g_nvram_btdata[1], g_nvram_btdata[2], + g_nvram_btdata[3], g_nvram_btdata[4], g_nvram_btdata[5], + g_nvram_btdata[6], g_nvram_btdata[7]); + + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb); + } + else { + BT_ERR_FUNC("STP is not ready\n"); + + /*return error code*/ + return -ENODEV; + } + +// init_MUTEX(&wr_mtx); + sema_init(&wr_mtx, 1); +// init_MUTEX(&rd_mtx); + sema_init(&rd_mtx, 1); + + 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 + ); + retflag = 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_INFO_FUNC("WMT turn off BT fail!\n"); + return -EIO; //mostly, native programmer will not check this return value. + } + else { + BT_INFO_FUNC("WMT turn off BT OK!\n"); + } + + return 0; +} + +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, + .poll = BT_poll +}; + +static int BT_init(void) +{ + dev_t dev = MKDEV(BT_major, 0); + int alloc_ret = 0; + int cdev_err = 0; + + /*static allocate chrdev*/ + alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME); + if (alloc_ret) { + BT_ERR_FUNC("fail to register chrdev\n"); + 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; + + BT_INFO_FUNC("%s driver(major %d) installed.\n", BT_DRIVER_NAME, BT_major); + retflag = 0; + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); + + /* init wait queue */ + init_waitqueue_head(&(inq)); + + return 0; + +error: + 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); + retflag = 0; + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); // unregister event callback function + + cdev_del(&BT_cdev); + unregister_chrdev_region(dev, BT_devs); + + BT_INFO_FUNC("%s driver removed.\n", BT_DRIVER_NAME); +} + +module_init(BT_init); +module_exit(BT_exit); + + diff --git a/drivers/mtk_wcn_combo/common/linux/stp_chrdev_gps.c b/drivers/mtk_wcn_combo/common/linux/stp_chrdev_gps.c new file mode 100755 index 000000000000..2ade72e50c63 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/stp_chrdev_gps.c @@ -0,0 +1,442 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/** $Log: stp_chrdev_gps.c $ + * + * 12 13 2010 Sean.Wang + * (1) Add GPS_DEBUG_TRACE_GPIO to disable GPIO debugging trace + * (2) Add GPS_DEBUG_DUMP to support GPS data dump + * (3) Add mtk_wcn_stp_is_ready() check in GPS_open() +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stp_exp.h" +#include "wmt_exp.h" + +MODULE_LICENSE("GPL"); + +#define GPS_DRIVER_NAME "mtk_stp_GPS_chrdev" +#define GPS_DEV_MAJOR 191 // never used number +#define GPS_DEBUG_TRACE_GPIO 0 +#define GPS_DEBUG_DUMP 0 + +#define PFX "[GPS] " +#define GPS_LOG_DBG 3 +#define GPS_LOG_INFO 2 +#define GPS_LOG_WARN 1 +#define GPS_LOG_ERR 0 + +#define COMBO_IOC_GPS_HWVER 6 + +unsigned int gDbgLevel = GPS_LOG_INFO;/*GPS_LOG_DBG*/ + +#define GPS_DBG_FUNC(fmt, arg...) if(gDbgLevel >= GPS_LOG_DBG){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define GPS_INFO_FUNC(fmt, arg...) if(gDbgLevel >= GPS_LOG_INFO){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define GPS_WARN_FUNC(fmt, arg...) if(gDbgLevel >= GPS_LOG_WARN){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define GPS_ERR_FUNC(fmt, arg...) if(gDbgLevel >= GPS_LOG_ERR){ printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define GPS_TRC_FUNC(f) if(gDbgLevel >= GPS_LOG_DBG){ printk(PFX "<%s> <%d>\n", __FUNCTION__, __LINE__);} + + +static int GPS_devs = 1; /* device count */ +static int GPS_major = GPS_DEV_MAJOR; /* dynamic allocation */ +module_param(GPS_major, uint, 0); +static struct cdev GPS_cdev; + +static unsigned char i_buf[MTKSTP_BUFFER_SIZE]; // input buffer of read() +static unsigned char o_buf[MTKSTP_BUFFER_SIZE]; // output buffer of write() +static struct semaphore wr_mtx, rd_mtx; +static DECLARE_WAIT_QUEUE_HEAD(GPS_wq); +static int flag = 0; + +static void GPS_event_cb(void); + +ssize_t GPS_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) +{ + int retval = 0; + int written = 0; + down(&wr_mtx); + + //GPS_TRC_FUNC(); + + /*printk("%s: count %d pos %lld\n", __func__, count, *f_pos);*/ + if (count > 0) + { + int copy_size = (count < MTKSTP_BUFFER_SIZE) ? count : MTKSTP_BUFFER_SIZE; + if (copy_from_user(&o_buf[0], &buf[0], copy_size)) + { + retval = -EFAULT; + goto out; + } + //printk("%02x ", val); +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_LOW); +#endif + written = mtk_wcn_stp_send_data(&o_buf[0], copy_size, GPS_TASK_INDX); +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_HIGH); +#endif + +#if GPS_DEBUG_DUMP +{ + unsigned char *buf_ptr = &o_buf[0]; + int k=0; + printk("--[GPS-WRITE]--"); + for(k=0; k < 10 ; k++){ + if(k%16 == 0) printk("\n"); + printk("0x%02x ", o_buf[k]); + } + printk("\n"); +} +#endif + /* + If cannot send successfully, enqueue again + + if (written != copy_size) { + // George: FIXME! Move GPS retry handling from app to driver + } + */ + if(0 == written) + { + retval = -ENOSPC; + /*no windowspace in STP is available, native process should not call GPS_write with no delay at all*/ + GPS_ERR_FUNC("target packet length:%d, write success length:%d, retval = %d.\n", count, written, retval); + } + else + { + retval = written; + } + } + else + { + retval = -EFAULT; + GPS_ERR_FUNC("target packet length:%d is not allowed, retval = %d.\n", count, retval); + } +out: + up(&wr_mtx); + return (retval); +} + +ssize_t GPS_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) +{ + long val = 0; + int retval; + + down(&rd_mtx); + +/* printk("GPS_read(): count %d pos %lld\n", count, *f_pos);*/ + + if(count > MTKSTP_BUFFER_SIZE) + { + count = MTKSTP_BUFFER_SIZE; + } + +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW); +#endif + retval = mtk_wcn_stp_receive_data(i_buf, count, GPS_TASK_INDX); +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH); +#endif + + while(retval == 0) // got nothing, wait for STP's signal + { + /*wait_event(GPS_wq, flag != 0);*/ /* George: let signal wake up */ + val = wait_event_interruptible(GPS_wq, flag != 0); + flag = 0; + +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_LOW); +#endif + + retval = mtk_wcn_stp_receive_data(i_buf, count, GPS_TASK_INDX); + +#if GPS_DEBUG_TRACE_GPIO + mtk_wcn_stp_debug_gpio_assert(IDX_GPS_RX, DBG_TIE_HIGH); +#endif + /* if we are signaled */ + if (val) { + if (-ERESTARTSYS == val) { + GPS_INFO_FUNC("signaled by -ERESTARTSYS(%ld) \n ", val); + } + else { + GPS_INFO_FUNC("signaled by %ld \n ", val); + } + break; + } + } + +#if GPS_DEBUG_DUMP +{ + unsigned char *buf_ptr = &i_buf[0]; + int k=0; + printk("--[GPS-READ]--"); + for(k=0; k < 10 ; k++){ + if(k%16 == 0) printk("\n"); + printk("0x%02x ", i_buf[k]); + } + printk("--\n"); +} +#endif + + if (retval) { + // we got something from STP driver + if (copy_to_user(buf, i_buf, retval)) { + retval = -EFAULT; + goto OUT; + } + else { + /* success */ + } + } + else { + // we got nothing from STP driver, being signaled + retval = val; + } + +OUT: + up(&rd_mtx); +/* printk("GPS_read(): retval = %d\n", retval);*/ + return (retval); +} + +//int GPS_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) +long GPS_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; + + GPS_DBG_FUNC("cmd (0x%x)\n", cmd); + + switch (cmd) + { + case COMBO_IOC_GPS_HWVER: + /*get combo hw version*/ + hw_ver_sym = mtk_wcn_wmt_hwver_get(); + GPS_INFO_FUNC("get hw version = %d, sizeof(hw_ver_sym) = %d\n", hw_ver_sym, sizeof(hw_ver_sym)); + if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) { + retval = -EFAULT; + } + break; + + default: + retval = -EFAULT; + GPS_DBG_FUNC(KERN_INFO "GPS_ioctl(): unknown cmd (0x%x)\n", cmd); + break; + } + + return retval; +} + +static void gps_cdev_rst_cb( + ENUM_WMTDRV_TYPE_T src, + ENUM_WMTDRV_TYPE_T dst, + ENUM_WMTMSG_TYPE_T type, + void *buf, + unsigned int sz){ + + /* + To handle reset procedure please + */ + ENUM_WMTRSTMSG_TYPE_T rst_msg; + + GPS_INFO_FUNC("sizeof(ENUM_WMTRSTMSG_TYPE_T) = %d\n", sizeof(ENUM_WMTRSTMSG_TYPE_T)); + if(sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)){ + memcpy((char *)&rst_msg, (char *)buf, sz); + GPS_INFO_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_GPS) && + (type == WMTMSG_TYPE_RESET)){ + if(rst_msg == WMTRSTMSG_RESET_START){ + GPS_INFO_FUNC("gps restart start!\n"); + + /*reset_start message handling*/ + + } else if(rst_msg == WMTRSTMSG_RESET_END){ + GPS_INFO_FUNC("gps restart end!\n"); + + /*reset_end message handling*/ + } + } + } else { + /*message format invalid*/ + } +} + +static int GPS_open(struct inode *inode, struct file *file) +{ + GPS_INFO_FUNC("major %d minor %d (pid %d)\n", + imajor(inode), + iminor(inode), + current->pid + ); + +#if 1 /* GeorgeKuo: turn on function before check stp ready */ + /* turn on BT */ + + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS)) { + GPS_WARN_FUNC("WMT turn on GPS fail!\n"); + return -ENODEV; + } else { + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_GPS, gps_cdev_rst_cb); + GPS_INFO_FUNC("WMT turn on GPS OK!\n"); + } +#endif + + if (mtk_wcn_stp_is_ready()) { +#if 0 + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS)) { + GPS_WARN_FUNC("WMT turn on GPS fail!\n"); + return -ENODEV; + } + GPS_INFO_FUNC("WMT turn on GPS OK!\n"); +#endif + mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, GPS_event_cb); + } else { + GPS_ERR_FUNC("STP is not ready, Cannot open GPS Devices\n\r"); + + /*return error code*/ + return -ENODEV; + } + + //init_MUTEX(&wr_mtx); + sema_init(&wr_mtx, 1); + //init_MUTEX(&rd_mtx); + sema_init(&rd_mtx, 1); + + return 0; +} + +static int GPS_close(struct inode *inode, struct file *file) +{ + GPS_INFO_FUNC("major %d minor %d (pid %d)\n", + imajor(inode), + iminor(inode), + current->pid + ); + + /*Flush Rx Queue*/ + mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, 0x0); // unregister event callback function + mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_GPS); + + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_GPS)) { + GPS_WARN_FUNC("WMT turn off GPS fail!\n"); + return -EIO; //mostly, native programer does not care this return vlaue, but we still return error code. + } + else { + GPS_INFO_FUNC("WMT turn off GPS OK!\n"); + } + + return 0; +} + +struct file_operations GPS_fops = { + .open = GPS_open, + .release = GPS_close, + .read = GPS_read, + .write = GPS_write, +// .ioctl = GPS_ioctl + .unlocked_ioctl = GPS_unlocked_ioctl, +}; + +void GPS_event_cb(void) +{ +/* printk("GPS_event_cb() \n");*/ + + flag = 1; + wake_up(&GPS_wq); + + return; +} + +static int GPS_init(void) +{ + dev_t dev = MKDEV(GPS_major, 0); + int alloc_ret = 0; + int cdev_err = 0; + + /*static allocate chrdev*/ + alloc_ret = register_chrdev_region(dev, 1, GPS_DRIVER_NAME); + if (alloc_ret) { + printk("fail to register chrdev\n"); + return alloc_ret; + } + + cdev_init(&GPS_cdev, &GPS_fops); + GPS_cdev.owner = THIS_MODULE; + + cdev_err = cdev_add(&GPS_cdev, dev, GPS_devs); + if (cdev_err) + goto error; + + printk(KERN_ALERT "%s driver(major %d) installed.\n", GPS_DRIVER_NAME, GPS_major); + + return 0; + +error: + if (cdev_err == 0) + cdev_del(&GPS_cdev); + + if (alloc_ret == 0) + unregister_chrdev_region(dev, GPS_devs); + + return -1; +} + +static void GPS_exit(void) +{ + dev_t dev = MKDEV(GPS_major, 0); + + cdev_del(&GPS_cdev); + unregister_chrdev_region(dev, GPS_devs); + + printk(KERN_ALERT "%s driver removed.\n", GPS_DRIVER_NAME); +} + +module_init(GPS_init); +module_exit(GPS_exit); + +EXPORT_SYMBOL(GPS_event_cb); + diff --git a/drivers/mtk_wcn_combo/common/linux/stp_exp.c b/drivers/mtk_wcn_combo/common/linux/stp_exp.c new file mode 100755 index 000000000000..b423fbbe14b2 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/stp_exp.c @@ -0,0 +1,304 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/***************************************************************************** +* Copyright Statement: +* -------------------- +* This software is protected by Copyright and the information contained +* herein is confidential. The software may not be copied and the information +* contained herein may not be used or disclosed except with the written +* permission of MediaTek Inc. (C) 2008 +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON +* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH +* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO +* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S +* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO +* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF +* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND +* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER +* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). +* +*****************************************************************************/ +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "osal_linux.h" +#include "core_exp.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 = NULL; +static MTK_WCN_STP_IF_TX stp_sdio_if_tx = NULL; +static ENUM_STP_TX_IF_TYPE g_stp_if_type = STP_MAX_IF_TX; +static MTK_WCN_STP_IF_RX stp_if_rx = NULL; +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); + } + else + { + (*stp_if_rx)(data, size); + return 0; + } +} + +static INT32 mtk_wcn_sys_if_tx ( + const UINT8 *data, + const UINT32 size, + UINT32 *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 (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 */ + printk(KERN_INFO "[%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) +{ + INT32 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 >= 0 && 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; +} + +INT32 mtk_wcn_stp_register_if_rx(MTK_WCN_STP_IF_RX func) +{ + stp_if_rx = func; + + return 0; +} + +VOID mtk_wcn_stp_set_if_tx_type ( + ENUM_STP_TX_IF_TYPE stp_if_type + ) +{ + g_stp_if_type = stp_if_type; + printk(KERN_INFO "[%s] set STP_IF_TX to %s.\n", + __FUNCTION__, + (STP_UART_IF_TX == stp_if_type)? "UART" : ((STP_SDIO_IF_TX == stp_if_type) ? "SDIO" : "NULL")); +} + +INT32 mtk_wcn_stp_register_if_tx ( + ENUM_STP_TX_IF_TYPE stp_if, + MTK_WCN_STP_IF_TX func + ) +{ + 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 + { + printk(KERN_WARNING "[%s] STP_IF_TX(%d) out of boundary.\n", __FUNCTION__, stp_if); + return -1; + } + + return 0; +} + +INT32 mtk_wcn_stp_register_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) +{ + if (type < MTKSTP_MAX_TASK_NUM) + { + event_callback_tbl[type] = func; + + /*clear rx queue*/ + //printk("Flush type = %d Rx Queue\n", type); + mtk_wcn_stp_flush_rx_queue(type); + } + + return 0; +} + +INT32 mtk_wcn_stp_register_tx_event_cb(INT32 type, MTK_WCN_STP_EVENT_CB func) +{ + if (type < MTKSTP_MAX_TASK_NUM) + { + tx_event_callback_tbl[type] = func; + } + else + { + BUG_ON(0); + } + + return 0; +} + +INT32 stp_drv_init(VOID) +{ + 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 + }; + + return mtk_wcn_stp_init(&cb); +} + +VOID stp_drv_exit(VOID) +{ + mtk_wcn_stp_deinit(); + + return; +} + +EXPORT_SYMBOL(mtk_wcn_stp_register_if_tx); +EXPORT_SYMBOL(mtk_wcn_stp_register_if_rx); +EXPORT_SYMBOL(mtk_wcn_stp_register_event_cb); +EXPORT_SYMBOL(mtk_wcn_stp_register_tx_event_cb); +EXPORT_SYMBOL(mtk_wcn_stp_parser_data); +EXPORT_SYMBOL(mtk_wcn_stp_send_data); +EXPORT_SYMBOL(mtk_wcn_stp_send_data_raw); +EXPORT_SYMBOL(mtk_wcn_stp_receive_data); +EXPORT_SYMBOL(mtk_wcn_stp_is_rxqueue_empty); +EXPORT_SYMBOL(mtk_wcn_stp_set_bluez); +EXPORT_SYMBOL(mtk_wcn_stp_is_ready); + + + + + + diff --git a/drivers/mtk_wcn_combo/common/linux/stp_uart.c b/drivers/mtk_wcn_combo/common/linux/stp_uart.c new file mode 100755 index 000000000000..5269d7c80a1d --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/stp_uart.c @@ -0,0 +1,1250 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +#define LDISC_LOW_LATENCY (0) +/* 1: set low_latency to tty; rx may be called in hw_irq context; +* 0: rx may be called in kernel global workqueue context (kthread) +*/ + +/* ldisc rx and do stp data parsing context options: + * LDISC_RX_TASKLET: + * use rx tasklet to process rx data in bh + * cons: can't sleep, priority too high. + * LDISC_RX_TTY_CB: + * process rx data directly in tty's recv callback context + * (ldisc.receive_buf). Real context type depends on LDISC_LOW_LATENCY: + * 1:interrupt context + * 0: thread context. + * cons: rx data may come too late. + * LDISC_RX_WORK (default): + * schedule another work_struct to handle + */ +#define LDISC_RX_TASKLET (0) +#define LDISC_RX_TTY_CB (1) +#define LDISC_RX_WORK (2) +/* Select LDISC RX Method */ +#define LDISC_RX (LDISC_RX_WORK) + +/* More detailed options */ +#if (LDISC_RX == LDISC_RX_TASKLET) +#define LDISC_RX_TASKLET_RWLOCK (0) +/* 1: use rwlock to protect rx kfifo (APEX default) for LDISC_RX_TASKLET + * 0: use _NO_ rwlock +*/ +#elif (LDISC_RX == LDISC_RX_WORK) +/* enable low latency mechanism */ +#undef LDISC_LOW_LATENCY +#define LDISC_LOW_LATENCY (1) +#endif + +/* ldisc tx context options: + * LDISC_TX_OLD: + * Do uart tx in the caller thread (STP-CORE). Handle local tx buffer + * in old way. + * LDISC_TX_CALLER_THRD: + * Do uart tx in the caller thread (STP-CORE). Handle tx using caller's + * buffer directly. + */ +#define LDISC_TX_OLD (0) +#define LDISC_TX_CALLER_THRD (1) + +/* Select LDISC TX Method */ +#define LDISC_TX (LDISC_TX_CALLER_THRD) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include /* vmalloc, vzalloc */ +#include /* INIT_WORK, schedule_work */ + +#include "stp_exp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define N_MTKSTP (15 + 1) /* refer to linux tty.h use N_HCI. */ +#define HCIUARTSETPROTO (_IOW('U', 200, int)) + +#define PFX "[STP-U]" +#define UART_LOG_LOUD (4) +#define UART_LOG_DBG (3) +#define UART_LOG_INFO (2) +#define UART_LOG_WARN (1) +#define UART_LOG_ERR (0) + +#define MAX_PACKET_ALLOWED (2000) + +#if (LDISC_RX == LDISC_RX_TASKLET) +#define LDISC_RX_FIFO_SIZE (0x20000/*0x2000*/) /* 128K or 8K bytes? */ + +#elif (LDISC_RX == LDISC_RX_WORK) +#define LDISC_RX_FIFO_SIZE (0x4000) /* 16K bytes shall be enough...... */ +#define LDISC_RX_BUF_SIZE (2048) /* 2K bytes in one shot is enough */ + +#endif + +#if (LDISC_TX == LDISC_TX_OLD) +/* no additional allocated for tx using caller's thread */ +//#define STP_UART_TX_BUF_SIZE (MTKSTP_BUFFER_SIZE) +#define STP_UART_TX_BUF_SIZE (4096) /* 16K or 4K bytes is enough? */ + +#elif (LDISC_TX == LDISC_TX_CALLER_THRD) + +#define LDISC_TX_CALLER_THRD_RTY_LMT (10) +#define LDISC_TX_CALLER_THRD_RTY_MIN_DLY (3) +#endif + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +unsigned int gStpDbgLevel = UART_LOG_ERR;//UART_LOG_INFO;//modify loglevel + +struct tty_struct *stp_tty = NULL; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +#if (LDISC_RX == LDISC_RX_TASKLET) +struct kfifo *g_stp_uart_rx_fifo = NULL; +spinlock_t g_stp_uart_rx_fifo_spinlock; +struct tasklet_struct g_stp_uart_rx_fifo_tasklet; + #if LDISC_RX_TASKLET_RWLOCK +static DEFINE_RWLOCK(g_stp_uart_rx_handling_lock); + #endif +#endif + +#if (LDISC_RX == LDISC_RX_WORK) +UINT8 *g_stp_uart_rx_buf; /* for stp rx data parsing */ +struct kfifo *g_stp_uart_rx_fifo = NULL; /* for uart tty data receiving */ +spinlock_t g_stp_uart_rx_fifo_spinlock; /* fifo spinlock */ +struct workqueue_struct *g_stp_uart_rx_wq; /* rx work queue (do not use system_wq) */ +struct work_struct *g_stp_uart_rx_work; /* rx work */ +#endif + +/* Private info for each Tx method */ +#if (LDISC_TX == LDISC_TX_OLD) +static unsigned char tx_buf[STP_UART_TX_BUF_SIZE] = {0x0}; +static unsigned int rd_idx = 0; /* the position next to read */ +static unsigned int wr_idx = 0; /* the position next to write */ +/* tx_buf in STP-UART is protected by caller(STP-CORE) locking mechanism. */ +//struct semaphore buf_mtx; /* unused */ +//static spinlock_t buf_lock; /* unused */ + +#elif (LDISC_TX == LDISC_TX_CALLER_THRD) +static int tx_retry_limit = LDISC_TX_CALLER_THRD_RTY_LMT; +static int tx_retry_delay_ms = LDISC_TX_CALLER_THRD_RTY_MIN_DLY; + +#else +#error "UNSUPPORTED LDISC_TX" LDISC_TX +#endif + +//static unsigned int tx_count = 0; /* drop tx data test? */ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +//#define MAX(a,b) ((a) > (b) ? (a) : (b)) //unused +//#define MIN(a,b) ((a) < (b) ? (a) : (b)) //unused + +#define UART_LOUD_FUNC(fmt, arg...) if(gStpDbgLevel >= UART_LOG_LOUD){ printk(PFX "[L]%s:" fmt, __FUNCTION__ ,##arg);} +#define UART_DBG_FUNC(fmt, arg...) if(gStpDbgLevel >= UART_LOG_DBG){ printk(PFX "[D]%s:" fmt, __FUNCTION__ ,##arg);} +#define UART_INFO_FUNC(fmt, arg...) if(gStpDbgLevel >= UART_LOG_INFO){ printk(PFX "[I]%s:" fmt, __FUNCTION__ ,##arg);} +#define UART_WARN_FUNC(fmt, arg...) if(gStpDbgLevel >= UART_LOG_WARN){ printk(PFX "[W]%s:" fmt, __FUNCTION__ ,##arg);} +#define UART_ERR_FUNC(fmt, arg...) if(gStpDbgLevel >= UART_LOG_ERR){ printk(PFX "[E]%s:" fmt, __FUNCTION__ ,##arg);} +#define UART_TRC_FUNC(f) if(gStpDbgLevel >= UART_LOG_DBG){ printk(PFX "<%s/%d>\n", __FUNCTION__, __LINE__);} + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +static INT32 mtk_wcn_uart_tx ( + const UINT8 *data, + const UINT32 size, + UINT32 *written_size + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#if (LDISC_TX == LDISC_TX_OLD) +static int stp_uart_tty_tx_init (void) +{ + //init_MUTEX(&buf_mtx); + //spin_lock_init(&buf_lock); + rd_idx = wr_idx = 0; + return 0; +} + +static int stp_uart_tty_tx_deinit (void) +{ + rd_idx = wr_idx = 0; + return 0; +} + +/* stp_uart_tty_open + * + * Arguments: + * tty pointer to tty info structure + * data pointer to data buffer to be written + * size data buffer length to be written + * Return Value: + * > 0 if success, otherwise error code + */ +static int stp_uart_tty_tx_write ( + struct tty_struct *tty, + const UINT8 *data, + const UINT32 size + ) +{ + int ret; + int len; + int written; + int written_count; + int room; + unsigned old_wr; + unsigned old_rd; + //unsigned long flags; + + UART_LOUD_FUNC("++\n"); + + /* Phase-I: put data into STP-UART ring buffer "tx_buf" */ + /* wr_idx : the position next to write + * rd_idx : the position next to read + */ + + //down(&buf_mtx); + /* [PatchNeed] spin_lock_irqsave is redundant */ + //spin_lock_irqsave(&buf_lock, flags); + old_wr = wr_idx; + old_rd = rd_idx; + + /* check left room size */ + room = (wr_idx >= rd_idx) + ? (STP_UART_TX_BUF_SIZE - (wr_idx - rd_idx) - 1) + : (rd_idx - wr_idx - 1); + UART_DBG_FUNC("before data in:r(%d)s(%d)wr_i(%d)rd_i(%d)\n", + room, size, wr_idx, rd_idx); + + if (unlikely(size > room)) { + UART_ERR_FUNC("buf unavailable FAIL#1,size(%d),wr_idx(%d),rd_idx(%d),room(%d),pid[%d/%s]\n", + size, wr_idx, rd_idx, room, current->pid, current->comm); + //up(&buf_mtx); + /* [PatchNeed] spin_lock_irqsave is redundant */ + //spin_unlock_irqrestore(&buf_lock, flags); + return -1; + } + else { + len = min(size, STP_UART_TX_BUF_SIZE - (unsigned int)wr_idx); + memcpy(&tx_buf[wr_idx], &data[0], len); + memcpy(&tx_buf[0], &data[len], size - len); + wr_idx = (wr_idx + size) % STP_UART_TX_BUF_SIZE; + UART_DBG_FUNC("after data in: r(%d)s(%d)wr_i(%d)rd_i(%d)\n", + room, size, wr_idx, rd_idx); + } + //up(&buf_mtx); + /* [PatchNeed] spin_lock_irqsave is redundant */ + //spin_unlock_irqrestore(&buf_lock, flags); + + /* Phase-II: get data from the buffer and send to tty UART. + * May be seperated into another context. + */ + + //down(&buf_mtx); + /* [PatchNeed] spin_lock_irqsave is redundant */ + //spin_lock_irqsave(&buf_lock, flags); + written_count = 0; + + len = (wr_idx >= rd_idx) ? (wr_idx - rd_idx) : (STP_UART_TX_BUF_SIZE - rd_idx); + if (likely(len > 0 && len < MAX_PACKET_ALLOWED)) + { + /* TTY_DO_WRITE_WAKEUP is used for "Call write_wakeup after queuing new" + * but stp_uart_tty_wakeup() is empty and unused now! + */ + //set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + + /* + * ops->write is called by the kernel to write a series of + * characters to the tty device. The characters may come from + * user space or kernel space. This routine will return the + * number of characters actually accepted for writing. + */ + written = tty->ops->write(tty, &tx_buf[rd_idx], len); + if (written != len) { + UART_ERR_FUNC("tty-ops->write FAIL#2,len(%d)wr(%d)wr_i(%d)rd_i(%d),pid[%d/%s]\n", + len, written, wr_idx, rd_idx, current->pid, current->comm); + ret = -2; + goto tx_write_out_unlock_old; + } + written_count = written; + rd_idx = ((rd_idx + written) % STP_UART_TX_BUF_SIZE); + + // all data is accepted by UART driver, check again in case roll over + len = (wr_idx >= rd_idx) ? (wr_idx - rd_idx) : (STP_UART_TX_BUF_SIZE - rd_idx); + if (len > 0 && len < MAX_PACKET_ALLOWED) + { + /* TTY_DO_WRITE_WAKEUP is used for "Call write_wakeup after queuing new" + * but stp_uart_tty_wakeup() is empty and unused now! + */ + //set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + + written = tty->ops->write(tty, &tx_buf[rd_idx], len); + if (unlikely(written != len)) + { + UART_ERR_FUNC("tty-ops->write FAIL#3,len(%d)wr(%d)wr_i(%d)rd_i(%d),pid[%d/%s]\n", + len, written, wr_idx, rd_idx, current->pid, current->comm); + ret = -3; + goto tx_write_out_unlock_old; + } + rd_idx = ((rd_idx + written) % STP_UART_TX_BUF_SIZE); + written_count += written; + } + else if (unlikely(len < 0 || len >= MAX_PACKET_ALLOWED)) + { + UART_ERR_FUNC("FAIL#4,len(%d)wr_i(%d)rd_i(%d),pid[%d/%s]\n", + len, wr_idx, rd_idx, + current->pid, current->comm); + ret = -4; + goto tx_write_out_unlock_old; + } + } + else + { + UART_ERR_FUNC("FAIL#5,len(%d)wr_i(%d)rd_i(%d),pid[%d/%s]\n", + len, wr_idx, rd_idx, + current->pid, current->comm); + ret = -5; + goto tx_write_out_unlock_old; + } + + /* success case */ + ret = written_count; + + +tx_write_out_unlock_old: + if (unlikely(ret < 0)) { + //reset read and write index of tx_buffer, is there any risk? + wr_idx = rd_idx = 0; + UART_ERR_FUNC("err(%d)reset fifo idx\n", ret); + } + + if (unlikely(wr_idx != rd_idx)) { + UART_WARN_FUNC("--wr(%d)rd(%d)size(%d)old wr(%d)rd(%d)\n", + wr_idx, rd_idx, size, old_wr, old_rd); + + } + else { + UART_LOUD_FUNC("--wr(%d) rd(%d)\n", wr_idx, rd_idx); + } + //up(&buf_mtx); + //spin_unlock_irqrestore(&buf_lock, flags); + + return ret; +} + +/* end of (LDISC_TX == LDISC_TX_OLD) */ + +#elif (LDISC_TX == LDISC_TX_CALLER_THRD) +static inline int stp_uart_tty_tx_init (void) +{ + /* nothing to be done */ + return 0; +} + +static inline int stp_uart_tty_tx_deinit (void) +{ + /* nothing to be done */ + return 0; +} + +static int stp_uart_tty_tx_write ( + struct tty_struct *tty, + const UINT8 *data, + const UINT32 size + ) +{ + int written; + int wr_count; + int retry_left; + int retry_delay_ms; + + wr_count = tty->ops->write(tty, data, size); + if (likely(wr_count == size)) { + /* perfect case! */ + return wr_count; + } + + UART_DBG_FUNC("tty write FAIL#1,size(%d)wr(%d)pid[%d/%s]\n", + size, written, current->pid, current->comm); + + /* error handling */ + retry_left = tx_retry_limit; + retry_delay_ms = tx_retry_delay_ms; + while ( (retry_left--) && (wr_count < size)) { + /* do msleep if and only if STP-CORE using process context (caller's or + * any other task) instead of any irq context (hardirq, softirq, tasklet + * , timer, etc). + */ + msleep(retry_delay_ms); + // TODO: to be refined by considering wr_count, current baud rate, etc. + retry_delay_ms *= 2; + written = tty->ops->write(tty, data + wr_count, size - wr_count); + wr_count += written; + } + + if (likely(wr_count == size)) { + UART_INFO_FUNC("recovered,size(%d)retry_left(%d)delay(%d)\n", + size, retry_left, retry_delay_ms); + /* workable case! */ + return wr_count; + } + + /* return -written_count as error code and let caller to further error handle */ + UART_ERR_FUNC("tty write FAIL#2,size(%d)wr(%d)retry_left(%d)pid[%d/%s]\n", + size, wr_count, retry_left, current->pid, current->comm); + + return -wr_count; +} +#else +#error "unknown LDISC_TX" LDISC_TX +#endif + +#if (LDISC_RX == LDISC_RX_TASKLET) +static int stp_uart_fifo_init(void) +{ + int err = 0; + + /*add rx fifo*/ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + { + spin_lock_init(&g_stp_uart_rx_fifo_spinlock); + g_stp_uart_rx_fifo = kfifo_alloc(LDISC_RX_FIFO_SIZE, GFP_ATOMIC, &g_stp_uart_rx_fifo_spinlock); + if (NULL == g_stp_uart_rx_fifo) + { + UART_ERR_FUNC("kfifo_alloc failed (kernel version < 2.6.33)\n"); + err = -1; + } + } + #else + { + g_stp_uart_rx_fifo = kzalloc(sizeof(struct kfifo), GFP_ATOMIC); + if (NULL == g_stp_uart_rx_fifo) + { + err = -2; + UART_ERR_FUNC("kzalloc for g_stp_uart_rx_fifo failed (kernel version > 2.6.33)\n"); + } + err = kfifo_alloc(g_stp_uart_rx_fifo, LDISC_RX_FIFO_SIZE, GFP_ATOMIC); + if (0 != err) + { + UART_ERR_FUNC("kfifo_alloc failed, errno(%d)(kernel version > 2.6.33)\n", err); + kfree(g_stp_uart_rx_fifo); + g_stp_uart_rx_fifo = NULL; + err = -3; + } + } + #endif + + if (0 == err) + { + if (NULL != g_stp_uart_rx_fifo) + { + kfifo_reset(g_stp_uart_rx_fifo); + UART_ERR_FUNC("stp_uart_fifo_init() success.\n"); + } + else + { + err = -4; + UART_ERR_FUNC("abnormal case, err = 0 but g_stp_uart_rx_fifo = NULL, set err to %d\n", err); + } + } + else + { + UART_ERR_FUNC("stp_uart_fifo_init() failed.\n"); + } + return err; +} + +static int stp_uart_fifo_deinit(void) +{ + if (NULL != g_stp_uart_rx_fifo) + { + kfifo_free(g_stp_uart_rx_fifo); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + //do nothing + #else + kfree(g_stp_uart_rx_fifo); + #endif + g_stp_uart_rx_fifo = NULL; + } + return 0; +} + +static void stp_uart_rx_handling(unsigned long func_data){ + #define LOCAL_BUFFER_LEN 1024 + unsigned char data[LOCAL_BUFFER_LEN]; + unsigned int how_much_get = 0; + unsigned int how_much_to_get = 0; + unsigned int flag = 0; + +#if LDISC_RX_TASKLET_RWLOCK + read_lock(&g_stp_uart_rx_handling_lock); +#endif + + how_much_to_get = kfifo_len(g_stp_uart_rx_fifo); + + if (how_much_to_get >= LOCAL_BUFFER_LEN) + { + flag = 1; + UART_INFO_FUNC ("fifolen(%d)\n", how_much_to_get); + } + + do { + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + how_much_get= kfifo_get(g_stp_uart_rx_fifo, data, LOCAL_BUFFER_LEN); + #else + how_much_get= kfifo_out(g_stp_uart_rx_fifo, data, LOCAL_BUFFER_LEN); + #endif + UART_INFO_FUNC ("fifoget(%d)\n", how_much_get); + mtk_wcn_stp_parser_data((UINT8 *)data, how_much_get); + how_much_to_get = kfifo_len(g_stp_uart_rx_fifo); + }while(how_much_to_get > 0); + +#if LDISC_RX_TASKLET_RWLOCK + read_unlock(&g_stp_uart_rx_handling_lock); +#endif + + if (1 == flag) + { + UART_INFO_FUNC ("finish, fifolen(%d)\n", kfifo_len(g_stp_uart_rx_fifo)); + } +} + +/* stp_uart_tty_receive() + * + * Called by tty low level driver when receive data is + * available. + * + * Arguments: tty pointer to tty isntance data + * data pointer to received data + * flags pointer to flags for data + * count count of received data in bytes + * + * Return Value: None + */ +static void stp_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) +{ + unsigned int fifo_avail_len;/* = LDISC_RX_FIFO_SIZE - kfifo_len(g_stp_uart_rx_fifo);*/ + unsigned int how_much_put = 0; + +#if 0 + { + struct timeval now; + do_gettimeofday(&now); + printk("[+STP][ ][R] %4d --> sec = %lu, --> usec --> %lu\n", + count, now.tv_sec, now.tv_usec); + } +#endif + +#if LDISC_RX_TASKLET_RWLOCK + write_lock(&g_stp_uart_rx_handling_lock); +#endif + + if (count > 2000) { + /*this is abnormal*/ + UART_ERR_FUNC("abnormal: buffer count = %d\n", count); + } + /*How much empty seat?*/ + fifo_avail_len = LDISC_RX_FIFO_SIZE - kfifo_len(g_stp_uart_rx_fifo); + if (fifo_avail_len > 0) { + //UART_INFO_FUNC ("fifo left(%d), count(%d)\n", fifo_avail_len, count); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + how_much_put = kfifo_put(g_stp_uart_rx_fifo,(unsigned char *) data, count); + #else + how_much_put = kfifo_in(g_stp_uart_rx_fifo,(unsigned char *) data, count); + #endif + +#if LDISC_RX_TASKLET_RWLOCK + /* George Test */ + write_unlock(&g_stp_uart_rx_handling_lock); +#endif + + /*schedule it!*/ + tasklet_schedule(&g_stp_uart_rx_fifo_tasklet); + } + else { + UART_ERR_FUNC("stp_uart_tty_receive rxfifo is full!!\n"); + } + +#if 0 + { + struct timeval now; + do_gettimeofday(&now); + printk("[-STP][ ][R] %4d --> sec = %lu, --> usec --> %lu\n", + count, now.tv_sec, now.tv_usec); + } +#endif + +#if LDISC_RX_TASKLET_RWLOCK + /* George Test */ + //write_unlock(&g_stp_uart_rx_handling_lock); +#endif + +} + +#elif (LDISC_RX == LDISC_RX_TTY_CB) +/* stp_uart_tty_receive() + * + * Called by tty low level driver when receive data is + * available. + * + * Arguments: tty pointer to tty isntance data + * data pointer to received data + * flags pointer to flags for data + * count count of received data in bytes + * + * Return Value: None + */ +static void stp_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) +{ + //UART_INFO_FUNC("count = %d\n", count); + + if (count > 2000){ + /*this is abnormal*/ + UART_WARN_FUNC("count = %d\n", count); + } + +#if 0 + { + struct timeval now; + + do_gettimeofday(&now); + + printk("[+STP][ ][R] %4d --> sec = %d, --> usec --> %d\n", + count, now.tv_sec, now.tv_usec); + } +#endif + + + /*There are multi-context to access here? Need to spinlock?*/ + /*Only one context: flush_to_ldisc in tty_buffer.c*/ + mtk_wcn_stp_parser_data((UINT8 *)data, (UINT32)count); + + /* George Test: useless? */ + /*tty_unthrottle(tty);*/ + +#if 0 + { + struct timeval now; + + do_gettimeofday(&now); + + printk("[-STP][ ][R] %4d --> sec = %d, --> usec --> %d\n", + count, now.tv_sec, now.tv_usec); + } +#endif + return; +} + +#elif (LDISC_RX == LDISC_RX_WORK) +static int stp_uart_fifo_init(void) +{ + int err = 0; + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) + g_stp_uart_rx_buf = vzalloc(LDISC_RX_BUF_SIZE); + if (!g_stp_uart_rx_buf) { + UART_ERR_FUNC("kfifo_alloc failed (kernel version >= 2.6.37)\n"); + err = -4; + goto fifo_init_end; + } + #else + g_stp_uart_rx_buf = vmalloc(LDISC_RX_BUF_SIZE); + if (!g_stp_uart_rx_buf) { + UART_ERR_FUNC("kfifo_alloc failed (kernel version < 2.6.37)\n"); + err = -4; + goto fifo_init_end; + } + memset(g_stp_uart_rx_buf, 0, LDISC_RX_BUF_SIZE); + #endif + + UART_LOUD_FUNC("g_stp_uart_rx_buf alloc ok(0x%p, %d)\n", + g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE); + + /*add rx fifo*/ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + spin_lock_init(&g_stp_uart_rx_fifo_spinlock); + g_stp_uart_rx_fifo = kfifo_alloc(LDISC_RX_FIFO_SIZE, GFP_KERNEL, &g_stp_uart_rx_fifo_spinlock); + if (NULL == g_stp_uart_rx_fifo) { + UART_ERR_FUNC("kfifo_alloc failed (kernel version < 2.6.33)\n"); + err = -1; + goto fifo_init_end; + } + #else + /* allocate struct kfifo first */ + g_stp_uart_rx_fifo = kzalloc(sizeof(struct kfifo), GFP_KERNEL); + if (NULL == g_stp_uart_rx_fifo) { + err = -2; + UART_ERR_FUNC("kzalloc struct kfifo failed (kernel version > 2.6.33)\n"); + goto fifo_init_end; + } + + /* allocate kfifo data buffer then */ + err = kfifo_alloc(g_stp_uart_rx_fifo, LDISC_RX_FIFO_SIZE, GFP_KERNEL); + if (0 != err) { + UART_ERR_FUNC("kfifo_alloc failed, err(%d)(kernel version > 2.6.33)\n", err); + kfree(g_stp_uart_rx_fifo); + g_stp_uart_rx_fifo = NULL; + err = -3; + goto fifo_init_end; + } + #endif + UART_LOUD_FUNC("g_stp_uart_rx_fifo alloc ok\n"); + +fifo_init_end: + + if (0 == err) { + /* kfifo init ok */ + kfifo_reset(g_stp_uart_rx_fifo); + UART_DBG_FUNC("g_stp_uart_rx_fifo init success\n"); + } + else { + UART_ERR_FUNC("stp_uart_fifo_init() fail(%d)\n", err); + if (g_stp_uart_rx_buf) { + UART_ERR_FUNC("free g_stp_uart_rx_buf\n"); + vfree(g_stp_uart_rx_buf); + g_stp_uart_rx_buf = NULL; + } + } + + return err; +} + +static int stp_uart_fifo_deinit(void) +{ + if (g_stp_uart_rx_buf) { + vfree(g_stp_uart_rx_buf); + g_stp_uart_rx_buf = NULL; + } + + if (NULL != g_stp_uart_rx_fifo) { + kfifo_free(g_stp_uart_rx_fifo); + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + //do nothing + #else + kfree(g_stp_uart_rx_fifo); + #endif + g_stp_uart_rx_fifo = NULL; + } + return 0; +} + +static void stp_uart_rx_worker (struct work_struct *work) +{ + unsigned int read; + + if (unlikely(!g_stp_uart_rx_fifo)) { + UART_ERR_FUNC("NULL rx fifo!\n"); + return; + } + if (unlikely(!g_stp_uart_rx_buf)) { + UART_ERR_FUNC("NULL rx buf!\n"); + return; + } + + /* run until fifo becomes empty */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + while (kfifo_len(g_stp_uart_rx_fifo)) { + read = kfifo_get(g_stp_uart_rx_fifo, g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE); + //UART_LOUD_FUNC("kfifo_get(%d)\n", read); + if (likely(read)) { + mtk_wcn_stp_parser_data((UINT8 *)g_stp_uart_rx_buf, read); + } + } +#else + while (!kfifo_is_empty(g_stp_uart_rx_fifo)) { + read = kfifo_out(g_stp_uart_rx_fifo, g_stp_uart_rx_buf, LDISC_RX_BUF_SIZE); + UART_DBG_FUNC("kfifo_out(%d)\n", read); + if (likely(read)) { + //UART_LOUD_FUNC("->%d\n", read); + mtk_wcn_stp_parser_data((UINT8 *)g_stp_uart_rx_buf, read); + //UART_LOUD_FUNC("<-\n", read); + } + } +#endif + + return; +} + +/* stp_uart_tty_receive() + * + * Called by tty low level driver when receive data is + * available. + * + * Arguments: tty pointer to tty isntance data + * data pointer to received data + * flags pointer to flags for data + * count count of received data in bytes + * + * Return Value: None + */ +static void stp_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) +{ + unsigned int written; + + //UART_LOUD_FUNC("URX:%d\n", count); + if (unlikely(count > 2000)) { + UART_WARN_FUNC("abnormal: buffer count = %d\n", count); + } + + if (unlikely(!g_stp_uart_rx_fifo || !g_stp_uart_rx_work || !g_stp_uart_rx_wq)) { + UART_ERR_FUNC("abnormal g_stp_uart_rx_fifo(0x%p),g_stp_uart_rx_work(0x%p),g_stp_uart_rx_wq(0x%p)\n", + g_stp_uart_rx_fifo, g_stp_uart_rx_work, g_stp_uart_rx_wq); + return; + } + + /* need to check available buffer size? skip! */ + + /* need to lock fifo? skip for single writer single reader! */ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + written = kfifo_put(g_stp_uart_rx_fifo, (unsigned char *) data, count); +#else + written = kfifo_in(g_stp_uart_rx_fifo, (unsigned char *) data, count); +#endif + queue_work(g_stp_uart_rx_wq, g_stp_uart_rx_work); + + if (unlikely(written != count)) { + UART_ERR_FUNC("c(%d),w(%d) bytes dropped\n", count, written); + } + + return; +} + +#else +#error "unknown LDISC_RX!" LDISC_RX +#endif + +/* ------ LDISC part ------ */ +/* stp_uart_tty_open + * + * Called when line discipline changed to HCI_UART. + * + * Arguments: + * tty pointer to tty info structure + * Return Value: + * 0 if success, otherwise error code + */ +static int stp_uart_tty_open(struct tty_struct *tty) +{ + UART_DBG_FUNC("original receive_room(%d) low_latency(%d) in tty(%p)\n", + tty->receive_room, tty->low_latency, tty); + + tty->receive_room = 65536; +#if LDISC_LOW_LATENCY + tty->low_latency = 1; +#endif + UART_DBG_FUNC("set receive_room(%d) low_latency(%d) to tty(%p)\n", + tty->receive_room, tty->low_latency, tty); + + /* Flush any pending characters in the driver and line discipline. */ + + /* FIXME: why is this needed. Note don't use ldisc_ref here as the + open path is before the ldisc is referencable */ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) + /* definition changed!! */ + if (tty->ldisc->ops->flush_buffer) { + tty->ldisc->ops->flush_buffer(tty); + } +#else + if (tty->ldisc.ops->flush_buffer) { + tty->ldisc.ops->flush_buffer(tty); + } +#endif + + tty_driver_flush_buffer(tty); + + stp_uart_tty_tx_init(); + + stp_tty = tty; + + /* Register to STP-CORE */ + mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, mtk_wcn_uart_tx); + + return 0; +} + +/* stp_uart_tty_close() + * + * Called when the line discipline is changed to something + * else, the tty is closed, or the tty detects a hangup. + */ +static void stp_uart_tty_close(struct tty_struct *tty) +{ + UART_DBG_FUNC("stp_uart_tty_close(): tty %p\n", tty); + mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, NULL); + + stp_uart_tty_tx_deinit(); + + return; +} + +/* stp_uart_tty_wakeup() + * + * Callback for transmit wakeup. Called when low level + * device driver can accept more send data. + * + * Arguments: tty pointer to associated tty instance data + * Return Value: None + */ +static void stp_uart_tty_wakeup(struct tty_struct *tty) +{ + /* + UART_INFO_FUNC("in\n"); + clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); + stp_uart_tx_wakeup(tty); + */ + + return; +} + +/* stp_uart_tty_ioctl() + * + * Process IOCTL system call for the tty device. + * + * Arguments: + * + * tty pointer to tty instance data + * file pointer to open file object for device + * cmd IOCTL command code + * arg argument for IOCTL call (cmd dependent) + * + * Return Value: Command dependent + */ +static int stp_uart_tty_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) +{ + int err = 0; + + UART_LOUD_FUNC("++ ll(%d)\n", tty->low_latency); + + switch (cmd) { + case HCIUARTSETPROTO: +#if LDISC_LOW_LATENCY + UART_INFO_FUNC("set low_latency to 1\n"); + tty->low_latency = 1; +#endif + break; + default: + UART_LOUD_FUNC("redirect to n_tty_ioctl_helper\n"); + err = n_tty_ioctl_helper(tty, file, cmd, arg); + UART_LOUD_FUNC("n_tty_ioctl_helper result(0x%x %d)\n", cmd, err); + break; + }; + + UART_LOUD_FUNC("--\n"); + return err; +} + +/* + * We don't provide read/write/poll interface for user space. + */ +static ssize_t stp_uart_tty_read(struct tty_struct *tty, struct file *file, + unsigned char __user *buf, size_t nr) +{ + return 0; +} + +static ssize_t stp_uart_tty_write(struct tty_struct *tty, struct file *file, + const unsigned char *data, size_t count) +{ + return 0; +} + +static unsigned int stp_uart_tty_poll(struct tty_struct *tty, + struct file *filp, poll_table *wait) +{ + return 0; +} + +static INT32 mtk_wcn_uart_tx ( + const UINT8 *data, + const UINT32 size, + UINT32 *written_size + ) +{ + INT32 ret; + int tx_len; + + if (unlikely(0 == size)) { + /* special case for STP-CORE, return ASAP. */ + if (likely(written_size)) { + *written_size = 0; + } + return 0; + } + + UART_LOUD_FUNC("++\n"); + + /* input sanity checks */ + if (unlikely(stp_tty == NULL)) { + UART_ERR_FUNC("NULL stp_tty,pid[%d/%s]\n", current->pid, current->comm); + ret = -1; + goto uart_tx_out; + } + + if (unlikely((data == NULL) || (written_size == NULL))) { + UART_ERR_FUNC("NULL data(0x%p) or written(0x%p),pid[%d/%s]\n", + data, written_size, current->pid, current->comm); + ret = -2; + goto uart_tx_out; + } + + *written_size = 0; + + /* Do size checking. Only 1~MAX_PACKET_ALLOWED-1 is allowed */ + if (unlikely(MAX_PACKET_ALLOWED <= size)) { + UART_ERR_FUNC("abnormal size(%d),skip tx,pid[%d/%s]\n", + size, current->pid, current->comm); + dump_stack(); + ret = -3; + goto uart_tx_out; + } + +#if 0 /* drop data test */ + if ((tx_count > 1000) && (tx_count % 5)== 0) { + UART_INFO_FUNC("i=(%d), ****** drop data from uart******\n", i); + ++tx_count; + return 0; + } +#endif + + tx_len = stp_uart_tty_tx_write(stp_tty, data, size); + if (unlikely(tx_len < 0)) { + UART_WARN_FUNC("stp_uart_tty_tx_write err(%d)\n", tx_len); + *written_size = 0; + ret = -4; + } + else { + *written_size = tx_len; + ret = 0; + } + +uart_tx_out: + UART_LOUD_FUNC("--(%d, %d)\n", ret, *written_size); + + return ret; +} + +static int __init mtk_wcn_stp_uart_init(void) +{ + static struct tty_ldisc_ops stp_uart_ldisc; + int err; + int fifo_init_done; + + UART_INFO_FUNC("MTK STP UART driver\n"); + + fifo_init_done = 0; + +#if (LDISC_RX == LDISC_RX_TASKLET) + err = stp_uart_fifo_init(); + if (err != 0) { + UART_ERR_FUNC("stp_uart_fifo_init(TASKLET) error(%d)\n", err); + err = -EFAULT; + goto init_err; + } + fifo_init_done = 1; + + /*init rx tasklet*/ + tasklet_init(&g_stp_uart_rx_fifo_tasklet, stp_uart_rx_handling, (unsigned long) 0); + +#elif (LDISC_RX == LDISC_RX_WORK) + err = stp_uart_fifo_init(); + if (err != 0) { + UART_ERR_FUNC("stp_uart_fifo_init(WORK) error(%d)\n", err); + err = -EFAULT; + goto init_err; + } + fifo_init_done = 1; + + g_stp_uart_rx_work = vmalloc(sizeof(struct work_struct)); + if (!g_stp_uart_rx_work) { + UART_ERR_FUNC("vmalloc work_struct(%d) fail\n", sizeof(struct work_struct)); + err = -ENOMEM; + goto init_err; + } + + g_stp_uart_rx_wq = create_singlethread_workqueue("mtk_urxd"); + if (!g_stp_uart_rx_wq) { + UART_ERR_FUNC("create_singlethread_workqueue fail\n"); + err = -ENOMEM; + goto init_err; + } + + /* init rx work */ + INIT_WORK(g_stp_uart_rx_work, stp_uart_rx_worker); +#endif + + /* Register the tty discipline */ + memset(&stp_uart_ldisc, 0, sizeof (stp_uart_ldisc)); + stp_uart_ldisc.magic = TTY_LDISC_MAGIC; + stp_uart_ldisc.name = "n_mtkstp"; + stp_uart_ldisc.open = stp_uart_tty_open; + stp_uart_ldisc.close = stp_uart_tty_close; + stp_uart_ldisc.read = stp_uart_tty_read; + stp_uart_ldisc.write = stp_uart_tty_write; + stp_uart_ldisc.ioctl = stp_uart_tty_ioctl; + stp_uart_ldisc.poll = stp_uart_tty_poll; + stp_uart_ldisc.receive_buf = stp_uart_tty_receive; + stp_uart_ldisc.write_wakeup = stp_uart_tty_wakeup; + stp_uart_ldisc.owner = THIS_MODULE; + + err = tty_register_ldisc(N_MTKSTP, &stp_uart_ldisc); + if (err) { + UART_ERR_FUNC("MTK STP line discipline(%d) registration failed. (%d)\n", N_MTKSTP, err); + goto init_err; + } + + /* init ok */ + return 0; + +init_err: + +#if (LDISC_RX == LDISC_RX_TASKLET) + /* nothing */ + if (fifo_init_done) { + stp_uart_fifo_deinit(); + } +#elif (LDISC_RX == LDISC_RX_WORK) + if (g_stp_uart_rx_wq) { + destroy_workqueue(g_stp_uart_rx_wq); + g_stp_uart_rx_wq = NULL; + } + if (g_stp_uart_rx_work) { + vfree(g_stp_uart_rx_work); + } + if (fifo_init_done) { + stp_uart_fifo_deinit(); + } +#endif + UART_ERR_FUNC("init fail, return(%d)\n", err); + + return err; +} + +static void __exit mtk_wcn_stp_uart_exit(void) +{ + int err; + + mtk_wcn_stp_register_if_tx(STP_UART_IF_TX, NULL); // unregister if_tx function + + /* Release tty registration of line discipline */ + if ((err = tty_unregister_ldisc(N_MTKSTP))) + { + UART_ERR_FUNC("Can't unregister MTK STP line discipline (%d)\n", err); + } + +#if (LDISC_RX == LDISC_RX_TASKLET) + tasklet_kill(&g_stp_uart_rx_fifo_tasklet); + stp_uart_fifo_deinit(); +#elif (LDISC_RX == LDISC_RX_WORK) + if (g_stp_uart_rx_work) { + cancel_work_sync(g_stp_uart_rx_work); + } + if (g_stp_uart_rx_wq) { + destroy_workqueue(g_stp_uart_rx_wq); + g_stp_uart_rx_wq = NULL; + } + if (g_stp_uart_rx_work) { + vfree(g_stp_uart_rx_work); + g_stp_uart_rx_work = NULL; + } + stp_uart_fifo_deinit(); +#endif + + return; +} + +module_init(mtk_wcn_stp_uart_init); +module_exit(mtk_wcn_stp_uart_exit); + +//MODULE_LICENSE("Proprietary"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("MediaTek Inc WCN_SE_CS3"); +MODULE_DESCRIPTION("STP-HIF UART Interface"); + diff --git a/drivers/mtk_wcn_combo/common/linux/wmt_chrdev_wifi.c b/drivers/mtk_wcn_combo/common/linux/wmt_chrdev_wifi.c new file mode 100755 index 000000000000..7c95cd4b8541 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/wmt_chrdev_wifi.c @@ -0,0 +1,209 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OWIFIAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wmt_exp.h" + +MODULE_LICENSE("Dual BSD/GPL"); + +#define WIFI_DRIVER_NAME "mtk_wmt_WIFI_chrdev" +#define WIFI_DEV_MAJOR 194 // never used number + +#define PFX "[MTK-WIFI] " +#define WIFI_LOG_DBG 3 +#define WIFI_LOG_INFO 2 +#define WIFI_LOG_WARN 1 +#define WIFI_LOG_ERR 0 + + +unsigned int gDbgLevel = WIFI_LOG_ERR;//WIFI_LOG_INFO;//modify loglevel + +#define WIFI_DBG_FUNC(fmt, arg...) if (gDbgLevel >= WIFI_LOG_DBG) { printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define WIFI_INFO_FUNC(fmt, arg...) if (gDbgLevel >= WIFI_LOG_INFO) { printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define WIFI_WARN_FUNC(fmt, arg...) if (gDbgLevel >= WIFI_LOG_WARN) { printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define WIFI_ERR_FUNC(fmt, arg...) if (gDbgLevel >= WIFI_LOG_ERR) { printk(PFX "%s: " fmt, __FUNCTION__ ,##arg);} +#define WIFI_TRC_FUNC(f) if (gDbgLevel >= WIFI_LOG_DBG) {printk(PFX "<%s> <%d>\n", __FUNCTION__, __LINE__);} + +#define VERSION "1.0" + +static int WIFI_devs = 1; /* device count */ +static int WIFI_major = WIFI_DEV_MAJOR; /* dynamic allocation */ +module_param(WIFI_major, uint, 0); +static struct cdev WIFI_cdev; +volatile int retflag = 0; +static struct semaphore wr_mtx; + +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) +{ + int retval = -EIO; + char local[4] = {0}; + static int opened = 0; + + down(&wr_mtx); + + if (count > 0) { + + if (0 == copy_from_user(local, buf, (count > 4) ? 4 : count)) { + WIFI_INFO_FUNC("WIFI_write %c\n", local[0]); + if (local[0] == '0' && opened == 1) { + //TODO + //Configure the EINT pin to GPIO mode. + + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { + WIFI_INFO_FUNC("WMT turn off WIFI fail!\n"); + } + else { + WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); + opened = 0; + retval = count; + } + } + else if (local[0] == '1' && opened == 0) { + //TODO + //Disable EINT(external interrupt), and set the GPIO to EINT mode. + + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { + WIFI_WARN_FUNC("WMT turn on WIFI fail!\n"); + } + else { + opened = 1; + retval = count; + WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); + } + } + + } + } + + up(&wr_mtx); + return (retval); +} + + +struct file_operations WIFI_fops = { + .open = WIFI_open, + .release = WIFI_close, + .write = WIFI_write, +}; + +static int WIFI_init(void) +{ + dev_t dev = MKDEV(WIFI_major, 0); + int alloc_ret = 0; + int cdev_err = 0; + + /*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; + } + + sema_init(&wr_mtx, 1); + + WIFI_INFO_FUNC("%s driver(major %d) installed.\n", WIFI_DRIVER_NAME, WIFI_major); + retflag = 0; + + return 0; + +error: + 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; + + cdev_del(&WIFI_cdev); + unregister_chrdev_region(dev, WIFI_devs); + + WIFI_INFO_FUNC("%s driver removed.\n", WIFI_DRIVER_NAME); +} + +module_init(WIFI_init); +module_exit(WIFI_exit); + diff --git a/drivers/mtk_wcn_combo/common/linux/wmt_dev.c b/drivers/mtk_wcn_combo/common/linux/wmt_dev.c new file mode 100755 index 000000000000..39b27c397291 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/wmt_dev.c @@ -0,0 +1,906 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief brief description + + Detailed descriptions here. + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/******************************************************************************* +* 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_linux.h" +#include "osal_typedef.h" +#include "osal.h" +#include "wmt_dev.h" +#include "core_exp.h" + + +#define MTK_WMT_VERSION "Combo WMT Driver - v1.0" +#define MTK_WMT_DATE "2011/10/04" +#define WMT_DEV_MAJOR 190 // never used number +#define WMT_DEV_NUM 1 + +#define WMT_DEV_INIT_TO_MS (2 * 1000) // 2000 ms + +#if CFG_WMT_DBG_SUPPORT +#define WMT_DBG_PROCNAME "driver/wmt_dbg" +#endif + +#define WMT_DRIVER_NAME "mtk_stp_wmt" + + +/* Linux UCHAR 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] = {0}; +static UINT32 gLpbkBufLog; // George LPBK debug +static int gWmtInitDone = 0; +static wait_queue_head_t gWmtInitWq; + +#if CFG_WMT_DBG_SUPPORT +static struct proc_dir_entry *gWmtDbgEntry = NULL; +#endif + + +#if CFG_WMT_DBG_SUPPORT + +static INT32 wmt_dev_dbg_read(CHAR *page, CHAR **start, LONG off, INT32 count, INT32 *eof, VOID *data) +{ + return wmt_dbg_proc_read(page,start,off,count,eof,data); +} + + +static INT32 wmt_dev_dbg_write(struct file *file, const CHAR *buffer, ULONG count, VOID *data){ + + CHAR buf[256]; + CHAR *pBuf; + ULONG len = count; + + WMT_INFO_FUNC("write parameter len = %d\n\r", (int)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)/*copy_from_user(buf, buffer, len)*/){ + return -EFAULT; + } + buf[len] = '\0'; + WMT_INFO_FUNC("write parameter data = %s\n\r", buf); + pBuf = buf; + wmt_dbg_proc_write(pBuf); + return len; +} + +INT32 wmt_dev_dbg_setup(VOID) +{ + gWmtDbgEntry = create_proc_entry(WMT_DBG_PROCNAME, 0666, NULL); + if (gWmtDbgEntry == NULL){ + WMT_ERR_FUNC("Unable to create /proc entry\n\r"); + return -1; + } + gWmtDbgEntry->read_proc = wmt_dev_dbg_read; + gWmtDbgEntry->write_proc = wmt_dev_dbg_write; + return 0; +} + +INT32 wmt_dev_dbg_remove(VOID) +{ + if (NULL != gWmtDbgEntry) + { + remove_proc_entry(WMT_DBG_PROCNAME, NULL); + } + return 0; +} + +#endif + +INT32 wmt_dev_read_file ( + UCHAR *pName, + const u8 **ppBufPtr, + INT32 offset, + INT32 padSzBuf + ) +{ + INT32 iRet = -1; + struct file *fd; + //ssize_t iRet; + INT32 file_len; + INT32 read_len; + void *pBuf; + + //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; + + WMT_INFO_FUNC("open (%s) O_RDONLY, 0\n", pName); + fd = filp_open(pName, O_RDONLY, 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)\n", fd, cred->fsuid, cred->fsgid); + return -1; + } + + file_len = fd->f_path.dentry->d_inode->i_size; + 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; + } + } + + read_len = fd->f_op->read(fd, pBuf + padSzBuf, file_len, &fd->f_pos); + 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 ( + UCHAR *pPatchName, + OSAL_FIRMWARE **ppPatch, + INT32 padSzBuf + ) +{ + INT32 iRet = -1; + uid_t orig_uid; + gid_t orig_gid; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) + //struct cred *cred = get_task_cred(current); + struct cred *cred = (struct cred *)get_current_cred(); +#endif + + 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; + } + + *ppPatch = (OSAL_FIRMWARE *)kzalloc(sizeof(OSAL_FIRMWARE), /*GFP_KERNEL*/GFP_ATOMIC); + if (!(*ppPatch)) { + WMT_ERR_FUNC("kzalloc(%d) fail\n", sizeof(OSAL_FIRMWARE)); + return -2; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) + orig_uid = cred->fsuid; + orig_gid = cred->fsgid; + cred->fsuid = cred->fsgid = 0; +#else + orig_uid = current->fsuid; + orig_gid = current->fsgid; + current->fsuid = current->fsgid = 0; +#endif + + set_fs(get_ds()); + + /* load patch file from fs */ + iRet = wmt_dev_read_file(pPatchName, &((*ppPatch)->data), 0, padSzBuf); + set_fs(orig_fs); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) + cred->fsuid = orig_uid; + cred->fsgid = orig_gid; +#else + current->fsuid = orig_uid; + current->fsgid = orig_gid; +#endif + + if (iRet > 0) { + (*ppPatch)->size = iRet; + WMT_DBG_FUNC("load (%s) to addr(0x%p) success\n", pPatchName, (*ppPatch)->data); + return 0; + } + else { + kfree((*ppPatch)); + *ppPatch = NULL; + WMT_ERR_FUNC("load file (%s) fail, iRet(%d) \n", pPatchName, iRet); + return -1; + } +} + +//INT32 wmt_dev_patch_put(osal_firmware **ppPatch) +INT32 wmt_dev_patch_put(OSAL_FIRMWARE **ppPatch) + +{ + if (NULL != *ppPatch ) + { + if ((*ppPatch)->data) { + vfree((*ppPatch)->data); + (*ppPatch)->data = NULL; + } + kfree(*ppPatch); + *ppPatch = NULL; + } + return 0; + +} + +MTK_WCN_BOOL wmt_dev_is_file_exist(UCHAR *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; + +} + + +ssize_t +WMT_write ( + struct file *filp, + const char __user *buf, + size_t count, + loff_t *f_pos + ) +{ + INT32 iRet = 0; + UCHAR wrBuf[OSAL_NAME_MAX+1] = {0}; + INT32 copySize = (count < OSAL_NAME_MAX) ? count : OSAL_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[OSAL_NAME_MAX] = '\0'; + + if (!strncasecmp(wrBuf, "ok", OSAL_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; + PUCHAR pCmd = NULL; + UINT32 cmdLen = 0; + pCmd = wmt_lib_get_cmd(); + + if (pCmd != NULL) + { + cmdLen = osal_strlen(pCmd) < OSAL_NAME_MAX ? osal_strlen(pCmd) : OSAL_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) < OSAL_NAME_MAX ? osal_strlen(localBuf) : OSAL_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, (wait_queue_head_t *)pEvent->pWaitQueue, 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; + WMT_DBG_FUNC("cmd (%u), arg (0x%lx)\n", cmd, arg); + + switch(cmd) { + case 4: /* patch location */ + { +#if 0 + WMT_DBG_FUNC("old patch file: %s \n", pWmtDevCtx->cPatchName); + if (copy_from_user(pWmtDevCtx->cPatchName, (void *)arg, OSAL_NAME_MAX)) { + iRet = -EFAULT; + break; + } + pWmtDevCtx->cPatchName[OSAL_NAME_MAX] = '\0'; + WMT_DBG_FUNC("new patch file name: %s \n", pWmtDevCtx->cPatchName); +#endif + UCHAR cPatchName[OSAL_NAME_MAX + 1]; + if (copy_from_user(cPatchName, (void *)arg, OSAL_NAME_MAX)) { + iRet = -EFAULT; + break; + } + cPatchName[OSAL_NAME_MAX] = '\0'; + wmt_lib_set_patch_name(cPatchName); + } + break; + + case 5: /* 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 6: /* 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 7: + /*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 8: + 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] = (UINT32)&gLpbkBuf[0]; //packet buffer pointer + memcpy(&gLpbkBufLog, &gLpbkBuf[((effectiveLen >=4) ? effectiveLen-4:0)], 4); + pSignal->timeoutValue = MAX_EACH_WMT_CMD; + WMT_DBG_FUNC("OPID(%d)type(%d)start\n", + pOp->op.opId, + pOp->op.au4OpData[0]); + wmt_lib_disable_psm_monitor(); + bRet = wmt_lib_put_act_op(pOp); + wmt_lib_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; + } + else { + WMT_DBG_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(ULONG) + sizeof(UCHAR[2048]), gLpbkBuf, iRet)) { + iRet = -EFAULT; + break; + } + } + }while(0); + + break; +#if 0 + case 9: + { + #define LOG_BUF_SZ 300 + UCHAR buf[LOG_BUF_SZ]; + INT32 len = 0; + INT32 remaining = 0; + + remaining = mtk_wcn_stp_btm_get_dmp(buf, &len); + + if (remaining == 0){ + WMT_DBG_FUNC("waiting dmp \n"); + wait_event_interruptible(dmp_wq, dmp_flag != 0); + dmp_flag = 0; + remaining = mtk_wcn_stp_btm_get_dmp(buf, &len); + + //WMT_INFO_FUNC("len = %d ###%s#\n", len, buf); + } else { + WMT_LOUD_FUNC("no waiting dmp \n"); + } + + if (unlikely((len+sizeof(INT32)) >= LOG_BUF_SZ)){ + WMT_ERR_FUNC("len is larger buffer\n"); + iRet = -EFAULT; + goto fail_exit; + } + + buf[sizeof(INT32)+len]='\0'; + + if (copy_to_user((void *)arg, (UCHAR *)&len, sizeof(INT32))){ + iRet = -EFAULT; + goto fail_exit; + } + + if (copy_to_user((void *)arg + sizeof(INT32), buf, len)){ + iRet = -EFAULT; + goto fail_exit; + } + } + break; + + case 10: + { + WMT_INFO_FUNC("Enable combo trace32 dump\n"); + wmt_cdev_t32dmp_enable(); + WMT_INFO_FUNC("Enable STP debugging mode\n"); + mtk_wcn_stp_dbg_enable(); + } + break; + + case 11: + { + WMT_INFO_FUNC("Disable combo trace32 dump\n"); + wmt_cdev_t32dmp_disable(); + WMT_INFO_FUNC("Disable STP debugging mode\n"); + mtk_wcn_stp_dbg_disable(); + } + break; +#endif + default: + iRet = -EINVAL; + WMT_WARN_FUNC("unknown cmd (%d)\n", cmd); + break; + } + + + return iRet; +} + +static int WMT_open(struct inode *inode, struct file *file) +{ + WMT_INFO_FUNC("major %d minor %d (pid %d)\n", + imajor(inode), + iminor(inode), + current->pid + ); + + 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; +} + +ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); +ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); +long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); + +struct file_operations gWmtFops = { + .open = WMT_open, + .release = WMT_close, + .read = WMT_read, + .write = WMT_write, +// .ioctl = WMT_ioctl, + .unlocked_ioctl = WMT_unlocked_ioctl, + .poll = WMT_poll, +}; + + +static int WMT_init(void) +{ + dev_t devID = MKDEV(gWmtMajor, 0); + INT32 cdevErr = -1; + INT32 ret = -1; + + /* init start */ + gWmtInitDone = 0; + init_waitqueue_head((wait_queue_head_t *)&gWmtInitWq); + + WMT_INFO_FUNC("WMT Version= %s DATE=%s\n" , MTK_WMT_VERSION, MTK_WMT_DATE); + /* Prepare a UCHAR device */ + /*static allocate chrdev*/ + + 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 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 + + + WMT_INFO_FUNC("success \n"); + return 0; + +error: + + wmt_lib_deinit(); +#if CFG_WMT_DBG_SUPPORT + wmt_dev_dbg_remove(); + +#endif + if (cdevErr == 0) { + cdev_del(&gWmtCdev); + } + + if (ret == 0) { + unregister_chrdev_region(devID, WMT_DEV_NUM); + gWmtMajor = -1; + } + + stp_drv_exit(); + + WMT_ERR_FUNC("fail \n"); + + return -1; +} + +static void WMT_exit (void) +{ + dev_t dev = MKDEV(gWmtMajor, 0); + + + wmt_lib_deinit(); + +#if CFG_WMT_DBG_SUPPORT + wmt_dev_dbg_remove(); +#endif + + cdev_del(&gWmtCdev); + unregister_chrdev_region(dev, WMT_DEV_NUM); + gWmtMajor = -1; + + stp_drv_exit(); + + WMT_INFO_FUNC("done\n"); +} + +module_init(WMT_init); +module_exit(WMT_exit); +MODULE_LICENSE("Proprietary"); +MODULE_AUTHOR("MediaTek Inc WCN"); +MODULE_DESCRIPTION("MTK WCN combo driver for WMT character device"); + +module_param(gWmtMajor, uint, 0); + + diff --git a/drivers/mtk_wcn_combo/common/linux/wmt_exp.c b/drivers/mtk_wcn_combo/common/linux/wmt_exp.c new file mode 100755 index 000000000000..ca29f7e5430b --- /dev/null +++ b/drivers/mtk_wcn_combo/common/linux/wmt_exp.c @@ -0,0 +1,384 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#ifdef DFT_TAG +#undef DFT_TAG +#endif +#define DFT_TAG "[WMT-EXP]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal_typedef.h" +#include +#include +#include "core_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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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; + 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*/ + wmt_lib_disable_psm_monitor(); + bRet = wmt_lib_put_act_op(pOp); + wmt_lib_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_INFO_FUNC("OPID(%d) type(%d) ok\n", + pOp->op.opId, + pOp->op.au4OpData[0]); + } + return bRet; +} + +MTK_WCN_BOOL +mtk_wcn_wmt_func_off ( + ENUM_WMTDRV_TYPE_T type + ) +{ + return mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_OFF); +} +EXPORT_SYMBOL(mtk_wcn_wmt_func_off); + +MTK_WCN_BOOL +mtk_wcn_wmt_func_on ( + ENUM_WMTDRV_TYPE_T type + ) +{ + return mtk_wcn_wmt_func_ctrl(type, WMT_OPID_FUNC_ON); +} +EXPORT_SYMBOL(mtk_wcn_wmt_func_on); + +/* +return value: +enable/disable thermal sensor function: true(1)/false(0) +read thermal sensor function:thermal value + +*/ +INT8 +mtk_wcn_wmt_therm_ctrl ( + ENUM_WMTTHERM_TYPE_T eType + ) +{ + 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]); + + wmt_lib_disable_psm_monitor(); + bRet = wmt_lib_put_act_op(pOp); + wmt_lib_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*/ + pOpData->au4OpData[1] = (eType == WMTTHERM_READ) ? 0xFF : MTK_WCN_BOOL_FALSE;/*will return to function driver*/ + } + 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]; +} +EXPORT_SYMBOL(mtk_wcn_wmt_therm_ctrl); + +ENUM_WMTHWVER_TYPE_T +mtk_wcn_wmt_hwver_get (VOID) +{ + // 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_hwver(); +} +EXPORT_SYMBOL(mtk_wcn_wmt_hwver_get); + +MTK_WCN_BOOL +mtk_wcn_wmt_dsns_ctrl ( + ENUM_WMTDSNS_TYPE_T eType + ) +{ + 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) { + pOpData->au4OpData[0] = WMTDRV_TYPE_FM; + pOpData->au4OpData[1] = 0x0; + } + else { /* input sanity had been verified *//*if (eType == WMTDSNS_FM_ENABLE)*/ + pOpData->au4OpData[0] = WMTDRV_TYPE_FM; + pOpData->au4OpData[1] = 0x1; + } + + WMT_INFO_FUNC("OPID(%d) type(%d) start\n", + pOp->op.opId, + pOp->op.au4OpData[0]); + + wmt_lib_disable_psm_monitor(); + bRet = wmt_lib_put_act_op(pOp); + wmt_lib_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; +} +EXPORT_SYMBOL(mtk_wcn_wmt_dsns_ctrl); + +INT32 +mtk_wcn_wmt_msgcb_reg ( + ENUM_WMTDRV_TYPE_T eType, + PF_WMT_CB pCb + ) +{ + return (INT32)wmt_lib_msgcb_reg(eType, pCb); +} +EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_reg); + +INT32 +mtk_wcn_wmt_msgcb_unreg ( + ENUM_WMTDRV_TYPE_T eType + ) +{ + return (INT32)wmt_lib_msgcb_unreg(eType); +} +EXPORT_SYMBOL(mtk_wcn_wmt_msgcb_unreg); + +INT32 +mtk_wcn_stp_wmt_sdio_op_reg ( + PF_WMT_SDIO_PSOP own_cb + ) +{ + wmt_lib_ps_set_sdio_psop(own_cb); + return 0; +} +EXPORT_SYMBOL(mtk_wcn_stp_wmt_sdio_op_reg); + diff --git a/drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_hw_6620.c b/drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_hw_6620.c new file mode 100755 index 000000000000..47bf98d277dc --- /dev/null +++ b/drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_hw_6620.c @@ -0,0 +1,346 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* 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-CMB-HW]" + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "osal.h" +#include "mtk_wcn_cmb_hw.h" +#include "wmt_plat.h" +#include "wmt_exp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define DFT_RTC_STABLE_TIME 100 +#define DFT_LDO_STABLE_TIME 100 +#define DFT_RST_STABLE_TIME 30 +#define DFT_OFF_STABLE_TIME 10 +#define DFT_ON_STABLE_TIME 30 + +/******************************************************************************* +* 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 +******************************************************************************** +*/ + +PWR_SEQ_TIME gPwrSeqTime; + + + + +/******************************************************************************* +* 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_cmb_hw_pwr_off (VOID) +{ + INT32 iRet = 0; + WMT_INFO_FUNC("CMB-HW, hw_pwr_off start\n"); + + /*1. disable irq --> should be done when do wmt-ic swDeinit period*/ + // TODO:[FixMe][GeorgeKuo] clarify this + + /*2. set bgf eint/all eint to deinit state, namely input low state*/ + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + WMT_INFO_FUNC("CMB-HW, BGF_EINT IRQ unregistered and disabled\n"); + iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_DEINIT); + /* 2.1 set ALL_EINT pin to correct state even it is not used currently */ + iRet += wmt_plat_eirq_ctrl(PIN_ALL_EINT, PIN_STA_EINT_DIS); + WMT_INFO_FUNC("CMB-HW, ALL_EINT IRQ unregistered and disabled\n"); + iRet += wmt_plat_gpio_ctrl(PIN_ALL_EINT, PIN_STA_DEINIT); + /* 2.2 deinit gps sync */ + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_DEINIT); + + /*3. set audio interface to CMB_STUB_AIF_0, BT PCM OFF, I2S OFF*/ + iRet += wmt_plat_audio_ctrl(CMB_STUB_AIF_0, CMB_STUB_AIF_CTRL_DIS); + + /*4. set control gpio into deinit state, namely input low state*/ + iRet += wmt_plat_gpio_ctrl(PIN_SDIO_GRP, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_L); + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_L); + + /*5. set uart tx/rx into deinit state, namely input low state*/ + iRet += wmt_plat_gpio_ctrl(PIN_UART_GRP, PIN_STA_DEINIT); + + /* 6. Last, LDO output low */ + iRet += wmt_plat_gpio_ctrl(PIN_LDO, PIN_STA_OUT_L); + + /*7. deinit gps_lna*/ + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_DEINIT); + + WMT_INFO_FUNC("CMB-HW, hw_pwr_off finish\n"); + return iRet; +} + +INT32 +mtk_wcn_cmb_hw_pwr_on (VOID) +{ + static UINT32 _pwr_first_time = 1; + INT32 iRet = 0; + + WMT_INFO_FUNC("CMB-HW, hw_pwr_on start\n"); +#if 0 //IRQ should in inact state before power on, so this step is not needed + /* disable interrupt firstly */ + iRet += wmt_plat_eirq_ctrl(PIN_BGF_EINT, PIN_STA_EINT_DIS); + iRet += wmt_plat_eirq_ctrl(PIN_ALL_EINT, PIN_STA_EINT_DIS); +#endif + /*set all control and eint gpio to init state, namely input low mode*/ + iRet += wmt_plat_gpio_ctrl(PIN_LDO, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_SDIO_GRP, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_BGF_EINT, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_ALL_EINT, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_GPS_SYNC, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_GPS_LNA, PIN_STA_INIT); + // wmt_plat_gpio_ctrl(PIN_WIFI_EINT, PIN_STA_INIT); /* WIFI_EINT is controlled by SDIO host driver */ + // TODO: [FixMe][George]:WIFI_EINT is used in common SDIO + + /*1. pull high LDO to supply power to chip*/ + iRet += wmt_plat_gpio_ctrl(PIN_LDO, PIN_STA_OUT_H); + osal_msleep(gPwrSeqTime.ldoStableTime); + + /* 2. export RTC clock to chip*/ + if (_pwr_first_time) { + /* rtc clock should be output all the time, so no need to enable output again*/ + iRet += wmt_plat_gpio_ctrl(PIN_RTC, PIN_STA_INIT); + osal_msleep(gPwrSeqTime.rtcStableTime); + WMT_INFO_FUNC("CMB-HW, rtc clock exported\n"); + } + + /*3. set UART Tx/Rx to UART mode*/ + iRet += wmt_plat_gpio_ctrl(PIN_UART_GRP, PIN_STA_INIT); + + /*4. PMU->output low, RST->output low, sleep off stable time*/ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_L); + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_L); + osal_msleep(gPwrSeqTime.offStableTime); + + /*5. PMU->output high, sleep rst stable time*/ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_H); + osal_msleep(gPwrSeqTime.rstStableTime); + + /*6. RST->output high, sleep on stable time*/ + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_H); + osal_msleep(gPwrSeqTime.onStableTime); + + /*7. set audio interface to CMB_STUB_AIF_1, BT PCM ON, I2S OFF*/ + /* BT PCM bus default mode. Real control is done by audio */ + iRet += wmt_plat_audio_ctrl(CMB_STUB_AIF_1, CMB_STUB_AIF_CTRL_DIS); + + /*8. set EINT< -ommited-> move this to WMT-IC module, where common sdio interface will be identified and do proper operation*/ + // 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_INFO_FUNC("CMB-HW, BGF_EINT IRQ registered and disabled \n"); + + /* 8.1 set ALL_EINT pin to correct state even it is not used currently */ + iRet += wmt_plat_gpio_ctrl(PIN_ALL_EINT, PIN_STA_MUX); + iRet += wmt_plat_eirq_ctrl(PIN_ALL_EINT, PIN_STA_INIT); + iRet += wmt_plat_eirq_ctrl(PIN_ALL_EINT, PIN_STA_EINT_DIS); + WMT_INFO_FUNC("CMB-HW, hw_pwr_on finish (%d)\n", iRet); + + _pwr_first_time = 0; + return iRet; + +} + +INT32 +mtk_wcn_cmb_hw_rst (VOID) +{ + INT32 iRet = 0; + WMT_INFO_FUNC("CMB-HW, hw_rst start, eirq should be disabled before this step\n"); + + /*1. PMU->output low, RST->output low, sleep off stable time*/ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_L); + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_L); + osal_msleep(gPwrSeqTime.offStableTime); + + /*2. PMU->output high, sleep rst stable time*/ + iRet += wmt_plat_gpio_ctrl(PIN_PMU, PIN_STA_OUT_H); + osal_msleep(gPwrSeqTime.rstStableTime); + + /*3. RST->output high, sleep on stable time*/ + iRet += wmt_plat_gpio_ctrl(PIN_RST, PIN_STA_OUT_H); + osal_msleep(gPwrSeqTime.onStableTime); + WMT_INFO_FUNC("CMB-HW, hw_rst finish, eirq should be enabled after this step\n"); + return 0; +} + +static VOID +mtk_wcn_cmb_hw_dmp_seq (VOID) +{ + PUINT32 pTimeSlot = (PUINT32)&gPwrSeqTime; + WMT_INFO_FUNC("combo chip power on sequence time, RTC (%d), LDO (%d), RST(%d), OFF(%d), ON(%d)\n", + pTimeSlot[0], /**pTimeSlot++,*/ + pTimeSlot[1], + pTimeSlot[2], + pTimeSlot[3], + pTimeSlot[4] + ); + return; +} + +INT32 +mtk_wcn_cmb_hw_init ( + P_PWR_SEQ_TIME pPwrSeqTime + ) +{ + if (NULL != pPwrSeqTime && + pPwrSeqTime->ldoStableTime > 0 && + pPwrSeqTime->rtcStableTime > 0 && + pPwrSeqTime->offStableTime > DFT_OFF_STABLE_TIME && + pPwrSeqTime->onStableTime > DFT_ON_STABLE_TIME && + pPwrSeqTime->rstStableTime > DFT_RST_STABLE_TIME + ) { + /*memcpy may be more performance*/ + WMT_DBG_FUNC("setting hw init sequence parameters\n"); + osal_memcpy(&gPwrSeqTime, pPwrSeqTime, osal_sizeof(gPwrSeqTime)); + } + else { + WMT_WARN_FUNC("invalid pPwrSeqTime parameter, use default hw init sequence parameters\n"); + gPwrSeqTime.ldoStableTime = DFT_LDO_STABLE_TIME; + gPwrSeqTime.offStableTime = DFT_OFF_STABLE_TIME; + gPwrSeqTime.onStableTime = DFT_ON_STABLE_TIME; + gPwrSeqTime.rstStableTime = DFT_RST_STABLE_TIME; + gPwrSeqTime.rtcStableTime = DFT_RTC_STABLE_TIME; + } + mtk_wcn_cmb_hw_dmp_seq(); + return 0; +} + +INT32 +mtk_wcn_cmb_hw_deinit (VOID) +{ + + WMT_WARN_FUNC("mtk_wcn_cmb_hw_deinit start, set to default hw init sequence parameters\n"); + gPwrSeqTime.ldoStableTime = DFT_LDO_STABLE_TIME; + gPwrSeqTime.offStableTime = DFT_OFF_STABLE_TIME; + gPwrSeqTime.onStableTime = DFT_ON_STABLE_TIME; + gPwrSeqTime.rstStableTime = DFT_RST_STABLE_TIME; + gPwrSeqTime.rtcStableTime = DFT_RTC_STABLE_TIME; + WMT_WARN_FUNC("mtk_wcn_cmb_hw_deinit finish\n"); + return 0; +} + diff --git a/drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_stub_rockchip.c b/drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_stub_rockchip.c new file mode 100755 index 000000000000..69546c061c29 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/platform/rockchip/mtk_wcn_cmb_stub_rockchip.c @@ -0,0 +1,348 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define CMB_STUB_LOG_INFO(fmt, arg...) printk(KERN_INFO fmt, ##arg) +#define CMB_STUB_LOG_WARN(fmt, arg...) printk(KERN_WARNING fmt, ##arg) +#define CMB_STUB_LOG_DBG(fmt, arg...) printk(KERN_DEBUG fmt, ##arg) + + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +//#include +//#include /* clr_device_working_ability, MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE, MT65XX_PDN_PERI_MSDC2 */ +//#include +// TODO: [FixMe][GeorgeKuo] keep prototype unchanged temporarily. Replace it +// when integrate MT6628 & ALPS & other built-in modules, such as AUDIO. +//#include + +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + + + + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +static wmt_aif_ctrl_cb cmb_stub_aif_ctrl_cb = NULL; +static wmt_func_ctrl_cb cmb_stub_func_ctrl_cb = NULL; +static CMB_STUB_AIF_X cmb_stub_aif_stat = CMB_STUB_AIF_0; + +/* 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] + */ +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, +}; + +/******************************************************************************* +* 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 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; + + 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_LOG_INFO("[cmb_stub] unregistered \n"); /* KERN_DEBUG */ + + 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; + return ret; + } + else { + CMB_STUB_LOG_WARN("[cmb_stub] aif_ctrl_cb null \n"); + return -2; + } +} +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] + */ +int +mt_combo_audio_ctrl_ex (COMBO_AUDIO_STATE state, u32 clt_ctrl) +{ + /* input sanity check */ + if (COMBO_AUDIO_STATE_MAX < state) { + CMB_STUB_LOG_WARN("[cmb_stub] invalid COMBO_AUDIO_STATE(%d)\n", state); + return -1; + } + + return mtk_wcn_cmb_stub_aif_ctrl(audio2aif[state], + (clt_ctrl) ? CMB_STUB_AIF_CTRL_EN : CMB_STUB_AIF_CTRL_DIS ); +} +EXPORT_SYMBOL(mt_combo_audio_ctrl_ex); + +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); + +/*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; + + const char *combo_if_name[] = + { "COMBO_IF_UART", + "COMBO_IF_MSDC" + }; + + if(src != COMBO_IF_UART && src!= COMBO_IF_MSDC){ + 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); + } + + /*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); + } else { + //set_device_working_ability(MT65XX_PDN_PERI_UART3, DEEP_IDLE_STATE); + //enable_dpidle_by_bit(MT65XX_PDN_PERI_UART2); + } + ret = 0; + break; + + case COMBO_IF_MSDC: + if(enter == 0){ + //clr_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); + } else { + //set_device_working_ability(MT65XX_PDN_PERI_MSDC2, DEEP_IDLE_STATE); + } + ret = 0; + break; + + default: + ret = -1; + 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); + diff --git a/drivers/mtk_wcn_combo/common/platform/rockchip/wmt_plat_rockchip.c b/drivers/mtk_wcn_combo/common/platform/rockchip/wmt_plat_rockchip.c new file mode 100755 index 000000000000..22731d927bc0 --- /dev/null +++ b/drivers/mtk_wcn_combo/common/platform/rockchip/wmt_plat_rockchip.c @@ -0,0 +1,906 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + + +/*! \file + \brief Declaration of library functions + + Any definitions in this file will be shared among GLUE Layer and internal Driver Stack. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#if CONFIG_HAS_WAKELOCK +#include +#define CFG_WMT_WAKELOCK_SUPPORT 1 +#endif + + +#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 +******************************************************************************** +*/ + +/*s5p headers*/ +#include +#include + +/* MTK_WCN_COMBO header files */ +#include "wmt_plat.h" +#include "wmt_exp.h" +#include "mtk_wcn_cmb_hw.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 VOID wmt_plat_func_ctrl (UINT32 type, UINT32 on); +static VOID wmt_plat_bgf_eirq_cb (VOID); + +static INT32 wmt_plat_ldo_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_pmu_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_rtc_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_rst_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_bgf_eint_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_wifi_eint_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_all_eint_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_uart_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_pcm_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_i2s_ctrl (ENUM_PIN_STATE state); +static INT32 wmt_plat_sdio_pin_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 +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + + + + +#if CFG_WMT_WAKELOCK_SUPPORT +static OSAL_SLEEPABLE_LOCK gOsSLock; +static struct wake_lock wmtWakeLock; +#endif + +const static fp_set_pin gfp_set_pin_table[] = +{ + [PIN_LDO] = wmt_plat_ldo_ctrl, + [PIN_PMU] = wmt_plat_pmu_ctrl, + [PIN_RTC] = wmt_plat_rtc_ctrl, + [PIN_RST] = wmt_plat_rst_ctrl, + [PIN_BGF_EINT] = wmt_plat_bgf_eint_ctrl, + [PIN_WIFI_EINT] = wmt_plat_wifi_eint_ctrl, + [PIN_ALL_EINT] = wmt_plat_all_eint_ctrl, + [PIN_UART_GRP] = wmt_plat_uart_ctrl, + [PIN_PCM_GRP] = wmt_plat_pcm_ctrl, + [PIN_I2S_GRP] = wmt_plat_i2s_ctrl, + [PIN_SDIO_GRP] = wmt_plat_sdio_pin_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; + + /* input sanity check */ + if ( (CMB_STUB_AIF_MAX <= state) + || (CMB_STUB_AIF_CTRL_MAX <= ctrl) ) { + iRet = -1; + WMT_ERR_FUNC("WMT-PLAT: invalid para, state(%d), ctrl(%d),iRet(%d) \n", state, ctrl, iRet); + return iRet; + } + if (0/*I2S/PCM share pin*/) { + // TODO: [FixMe][GeorgeKuo] how about MT6575? The following is applied to MT6573E1 only!! + pinShare = 1; + WMT_INFO_FUNC( "PCM/I2S pin share\n"); + } + else{ //E1 later + pinShare = 0; + WMT_INFO_FUNC( "PCM/I2S pin seperate\n"); + } + + 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_PCM_GRP, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); + break; + + case CMB_STUB_AIF_1: + iRet += wmt_plat_gpio_ctrl(PIN_PCM_GRP, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_DEINIT); + break; + + case CMB_STUB_AIF_2: + iRet += wmt_plat_gpio_ctrl(PIN_PCM_GRP, PIN_STA_DEINIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); + break; + + case CMB_STUB_AIF_3: + iRet += wmt_plat_gpio_ctrl(PIN_PCM_GRP, PIN_STA_INIT); + iRet += wmt_plat_gpio_ctrl(PIN_I2S_GRP, PIN_STA_INIT); + break; + + default: + /* FIXME: move to cust folder? */ + WMT_ERR_FUNC("invalid state [%d]\n", state); + return -1; + break; + } + + if (CMB_STUB_AIF_CTRL_EN == ctrl) { + WMT_INFO_FUNC("call chip aif setting \n"); + /* need to control chip side GPIO */ + iRet += wmt_lib_set_aif(state, (pinShare) ? MTK_WCN_BOOL_TRUE : MTK_WCN_BOOL_FALSE); + } + else { + WMT_INFO_FUNC("skip chip aif setting \n"); + } + return iRet; + +} + +static VOID wmt_plat_func_ctrl (UINT32 type, UINT32 on) +{ + if (on) { + mtk_wcn_wmt_func_on((ENUM_WMTDRV_TYPE_T)type); + } + else { + mtk_wcn_wmt_func_off((ENUM_WMTDRV_TYPE_T)type); + } + return; +} + +#if CFG_WMT_PS_SUPPORT +irqreturn_t irq_handler(int i, void *arg) +{ + wmt_plat_bgf_eirq_cb(); + return IRQ_HANDLED; +} +#endif + +static VOID +wmt_plat_bgf_eirq_cb (VOID) +{ +#if CFG_WMT_PS_SUPPORT +//#error "need to disable EINT here" + WMT_INFO_FUNC("WMT-PLAT:BGFInt (++) \n"); + wmt_lib_ps_irq_cb(); + WMT_INFO_FUNC("WMT-PLAT:BGFInt (++) \n"); + +#else + return; +#endif + +} + +INT32 +wmt_plat_init (P_PWR_SEQ_TIME pPwrSeqTime) +{ + CMB_STUB_CB stub_cb; + /*PWR_SEQ_TIME pwr_seq_time;*/ + INT32 iret; + + stub_cb.aif_ctrl_cb = wmt_plat_audio_ctrl; + stub_cb.func_ctrl_cb = wmt_plat_func_ctrl; + stub_cb.size = sizeof(stub_cb); + + /* register to cmb_stub */ + iret = mtk_wcn_cmb_stub_reg(&stub_cb); + + /* init cmb_hw */ + iret += mtk_wcn_cmb_hw_init(pPwrSeqTime); + + /*init wmt function ctrl wakelock if wake lock is supported by host platform*/ + #ifdef CFG_WMT_WAKELOCK_SUPPORT + wake_lock_init(&wmtWakeLock, WAKE_LOCK_SUSPEND, "wmtFuncCtrl"); + osal_sleepable_lock_init(&gOsSLock); + #endif + + WMT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); + + return 0; +} + + +INT32 +wmt_plat_deinit (VOID) +{ + INT32 iret; + + /* 1. de-init cmb_hw */ + iret = mtk_wcn_cmb_hw_deinit(); + /* 2. unreg to cmb_stub */ + iret += mtk_wcn_cmb_stub_unreg(); + /*3. wmt wakelock deinit*/ + #ifdef CFG_WMT_WAKELOCK_SUPPORT + wake_lock_destroy(&wmtWakeLock); + osal_sleepable_lock_deinit(&gOsSLock); + WMT_DBG_FUNC("destroy wmtWakeLock\n"); + #endif + WMT_DBG_FUNC("WMT-PLAT: ALPS platform init (%d)\n", iret); + + return 0; +} + +INT32 wmt_plat_sdio_ctrl (WMT_SDIO_SLOT_NUM sdioPortType, ENUM_FUNC_STATE on) +{ + if (FUNC_OFF == on) { + /* add control logic here to generate SDIO CARD REMOVAL event to mmc/sd + * controller. SDIO card removal operation and remove success messages + * are expected. + */ + } + else { + /* add control logic here to generate SDIO CARD INSERTION event to mmc/sd + * controller. SDIO card detection operation and detect success messages + * are expected. + */ + } + return 0; +} + +INT32 +wmt_plat_irq_ctrl ( + ENUM_FUNC_STATE state + ) +{ + return -1; +} + + +static INT32 +wmt_plat_dump_pin_conf (VOID) +{ + WMT_INFO_FUNC( "[WMT-PLAT]=>dump wmt pin configuration start<=\n"); + WMT_INFO_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_cmb_hw_pwr_on(); + break; + + case FUNC_OFF: + ret = mtk_wcn_cmb_hw_pwr_off(); + break; + + case FUNC_RST: + ret = mtk_wcn_cmb_hw_rst(); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) in pwr_ctrl\n", state); + break; + } + + return ret; +} + +INT32 wmt_plat_ps_ctrl (ENUM_FUNC_STATE state) +{ + return -1; +} + +INT32 +wmt_plat_eirq_ctrl ( + ENUM_PIN_ID id, + ENUM_PIN_STATE state + ) +{ + INT32 iRet; + + // 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 ) ) { + iRet = -1; + WMT_WARN_FUNC("WMT-PLAT:invalid PIN_STATE(%d) in eirq_ctrl for PIN(%d), ret(%d) \n", state, id, iRet); + return iRet; + } + + iRet = -2; + switch (id) { + case PIN_BGF_EINT: + if (PIN_STA_INIT == state) { + + WMT_INFO_FUNC("WMT-PLAT:BGFInt (init) \n"); + } + else if (PIN_STA_EINT_EN == state) { + WMT_INFO_FUNC("WMT-PLAT:BGFInt (en) \n"); + } + else if (PIN_STA_EINT_DIS == state) { + WMT_INFO_FUNC("WMT-PLAT:BGFInt (dis) \n"); + } + else { + /* de-init: nothing to do in ALPS, such as un-registration... */ + WMT_INFO_FUNC("WMT-PLAT:BGFInt (deinit) \n"); + + } + iRet = 0; + break; + + case PIN_ALL_EINT: +#if 0 + if (PIN_STA_INIT == state) { + + WMT_DBG_FUNC("WMT-PLAT:ALLInt (INIT but not used yet) \n"); + } + else if (PIN_STA_EINT_EN == state) { + WMT_DBG_FUNC("WMT-PLAT:ALLInt (EN but not used yet) \n"); + } + else if (PIN_STA_EINT_DIS == state) { + WMT_DBG_FUNC("WMT-PLAT:ALLInt (DIS but not used yet) \n"); + } + else { + + WMT_DBG_FUNC("WMT-PLAT:ALLInt (DEINIT but not used yet) \n"); + /* de-init: nothing to do in ALPS, such as un-registration... */ + } +#else + WMT_DBG_FUNC("WMT-PLAT:ALLInt (not used yet) \n"); +#endif + iRet = 0; + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:unsupported EIRQ(PIN_ID:%d) in eirq_ctrl, ret (%d)\n", id, iRet); + iRet = -1; + break; + } + + return iRet; +} + +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 */ + } + else { + WMT_WARN_FUNC("WMT-PLAT: null fp for gpio_ctrl(%d)\n", id); + return -2; + } + } + WMT_ERR_FUNC("WMT-PLAT:[out of range] id(%d), state (%d)\n", id, state); + return -1; +} + +INT32 +wmt_plat_ldo_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch(state) + { + case PIN_STA_INIT: + /*set to gpio output low, disable pull*/ + WMT_DBG_FUNC("WMT-PLAT:LDO init (out 0) \n"); + break; + + case PIN_STA_OUT_H: + WMT_DBG_FUNC("WMT-PLAT:LDO (out 1) \n"); + break; + + case PIN_STA_OUT_L: + WMT_DBG_FUNC("WMT-PLAT:LDO (out 0) \n"); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable*/ + WMT_DBG_FUNC("WMT-PLAT:LDO deinit (in pd) \n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on LDO\n", state); + break; + } + return 0; +} + +INT32 +wmt_plat_pmu_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch(state) + { + case PIN_STA_INIT: + /*set to gpio output low, disable pull*/ + WMT_DBG_FUNC("WMT-PLAT:PMU init (out 0) \n"); + break; + + case PIN_STA_OUT_H: + WMT_DBG_FUNC("WMT-PLAT:PMU (out 1) \n"); + break; + + case PIN_STA_OUT_L: + WMT_DBG_FUNC("WMT-PLAT:PMU (out 0) \n"); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable*/ + WMT_DBG_FUNC("WMT-PLAT:PMU deinit (in pd) \n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on PMU\n", state); + break; + } + + return 0; +} + +INT32 +wmt_plat_rtc_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch(state) + { + case PIN_STA_INIT: + WMT_DBG_FUNC("WMT-PLAT:RTC init \n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on RTC\n", state); + break; + } + return 0; +} + + +INT32 +wmt_plat_rst_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch(state) + { + case PIN_STA_INIT: + /*set to gpio output low, disable pull*/ + WMT_DBG_FUNC("WMT-PLAT:RST init (out 0) \n"); + break; + + case PIN_STA_OUT_H: + WMT_DBG_FUNC("WMT-PLAT:RST (out 1) \n"); + break; + + case PIN_STA_OUT_L: + WMT_DBG_FUNC("WMT-PLAT:RST (out 0) \n"); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable*/ + WMT_DBG_FUNC("WMT-PLAT:RST deinit (in pd) \n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on RST\n", state); + break; + } + + return 0; +} + +INT32 +wmt_plat_bgf_eint_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch(state) + { + case PIN_STA_INIT: + /*set to gpio input low, pull down eanble*/ + WMT_DBG_FUNC("WMT-PLAT:BGFInt init(in pd) \n"); + break; + + case PIN_STA_MUX: + /*set to gpio EINT mode, pull down enable*/ + WMT_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*/ + WMT_DBG_FUNC("WMT-PLAT:BGFInt deinit(in pd) \n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on BGF EINT\n", state); + break; + } + return 0; +} + + +INT32 wmt_plat_wifi_eint_ctrl(ENUM_PIN_STATE state) +{ +#if 0 + switch(state) + { + case PIN_STA_INIT: + break; + case PIN_STA_MUX: + + break; + case PIN_STA_EINT_EN: + break; + case PIN_STA_EINT_DIS: + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable*/ + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on WIFI EINT\n", state); + break; + } +#else + WMT_INFO_FUNC("WMT-PLAT:WIFI EINT is controlled by MSDC driver \n"); +#endif + return 0; +} + + +INT32 +wmt_plat_all_eint_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch(state) + { + case PIN_STA_INIT: + /*set to gpio input low, pull down eanble*/ + WMT_DBG_FUNC("WMT-PLAT:ALLInt init(in pd) \n"); + break; + + case PIN_STA_MUX: + /*set to gpio EINT mode, pull down enable*/ + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable*/ + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on ALL EINT\n", state); + break; + } + return 0; +} + +INT32 wmt_plat_uart_ctrl(ENUM_PIN_STATE state) +{ + switch(state) + { + case PIN_STA_MUX: + case PIN_STA_INIT: + WMT_DBG_FUNC("WMT-PLAT:UART init (mode_01, uart) \n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + WMT_DBG_FUNC("WMT-PLAT:UART deinit (out 0) \n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on UART Group\n", state); + break; + } + + return 0; +} + + +INT32 wmt_plat_pcm_ctrl(ENUM_PIN_STATE state) +{ + switch(state) + { + case PIN_STA_MUX: + case PIN_STA_INIT: + /*set to PCM function*/ + WMT_DBG_FUNC("WMT-PLAT:PCM init (pcm) \n"); + break; + + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + WMT_DBG_FUNC("WMT-PLAT:PCM deinit (out 0) \n"); + break; + + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on PCM Group\n", state); + break; + } + return 0; +} + + +INT32 wmt_plat_i2s_ctrl(ENUM_PIN_STATE state) +{ +#ifndef FM_ANALOG_INPUT + switch(state) + { + case PIN_STA_INIT: + case PIN_STA_MUX: + /*set to I2S function*/ + WMT_DBG_FUNC("WMT-PLAT:I2S init \n"); + break; + case PIN_STA_IN_L: + case PIN_STA_DEINIT: + /*set to gpio input low, pull down enable*/ + WMT_DBG_FUNC("WMT-PLAT:I2S deinit (out 0) \n"); + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on I2S Group\n", state); + break; + } +#else + WMT_INFO_FUNC( "[MT6620]warnning:FM analog mode is set, no I2S GPIO settings should be modified by combo driver\n"); +#endif + + return 0; +} + +INT32 +wmt_plat_sdio_pin_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch (state) { + case PIN_STA_INIT: + case PIN_STA_MUX: + break; + case PIN_STA_DEINIT: + break; + default: + WMT_WARN_FUNC("WMT-PLAT:Warnning, invalid state(%d) on SDIO Group\n", state); + break; + } + return 0; +} + +static INT32 +wmt_plat_gps_sync_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch (state) { + case PIN_STA_INIT: + case PIN_STA_DEINIT: + /*set GPS_SYNC GPIO to GPIO mode, pull disable,output low*/ + break; + + case PIN_STA_MUX: + /*set GPS_SYNC GPIO to GPS_SYNC function*/ + break; + + default: + break; + } + return 0; +} + + +static INT32 +wmt_plat_gps_lna_ctrl ( + ENUM_PIN_STATE state + ) +{ + switch (state) { + case PIN_STA_INIT: + case PIN_STA_DEINIT: + /*set GPS_LNA GPIO to GPIO mode, pull disable,output low*/ + break; + case PIN_STA_OUT_H: + /*set GPS_LNA GPIO to GPIO mode, pull disable,output high*/ + break; + case PIN_STA_OUT_L: + /*set GPS_LNA GPIO to GPIO mode, pull disable,output low*/ + break; + + default: + WMT_WARN_FUNC("%d mode not defined for gps lna pin !!!\n", state); + break; + } + return 0; + +} + + + +INT32 wmt_plat_wake_lock_ctrl(ENUM_WL_OP opId) +{ +#ifdef CFG_WMT_WAKELOCK_SUPPORT + static INT32 counter = 0; + + + osal_lock_sleepable_lock( &gOsSLock); + if (WL_OP_GET == opId) + { + ++counter; + }else if (WL_OP_PUT == opId) + { + --counter; + } + osal_unlock_sleepable_lock( &gOsSLock); + if (WL_OP_GET == opId && counter == 1) + { + wake_lock(&wmtWakeLock); + WMT_DBG_FUNC("WMT-PLAT: after wake_lock(%d), counter(%d)\n", wake_lock_active(&wmtWakeLock), counter); + + } + else if (WL_OP_PUT == opId && counter == 0) + { + wake_unlock(&wmtWakeLock); + WMT_DBG_FUNC("WMT-PLAT: after wake_unlock(%d), counter(%d)\n", wake_lock_active(&wmtWakeLock), counter); + } + else + { + WMT_WARN_FUNC("WMT-PLAT: wakelock status(%d), counter(%d)\n", wake_lock_active(&wmtWakeLock), counter); + } + return 0; +#else + WMT_WARN_FUNC("WMT-PLAT: host awake function is not supported."); + return 0; + +#endif +} + diff --git a/drivers/mtk_wcn_combo/drv_bt/Makefile b/drivers/mtk_wcn_combo/drv_bt/Makefile new file mode 100755 index 000000000000..9cd070acd71a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_bt/Makefile @@ -0,0 +1,43 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# +# Makefile for the Linux Bluetooth HCI device drivers. +# +ccflags-y := -I$(src)/include -I$(src)/../common/include -I$(src)/../common/linux/include + +obj-$(CONFIG_MTK_COMBO_BT_HCI) += hci_stp.o +hci_stp-objs := linux/hci_stp.o + diff --git a/drivers/mtk_wcn_combo/drv_bt/include/hci_stp.h b/drivers/mtk_wcn_combo/drv_bt/include/hci_stp.h new file mode 100755 index 000000000000..adcd24d14fb3 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_bt/include/hci_stp.h @@ -0,0 +1,204 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* + * + * Bluetooth HCI UART driver + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#ifndef _HCI_STP_H +#define _HCI_STP_H + +#define HCI_STP_TX_TASKLET (0) /* do tx in a tasklet context */ +#define HCI_STP_TX_THRD (1) /* do tx in an init thread context */ + +/* select tx context */ +#define HCI_STP_TX (HCI_STP_TX_THRD) + +#if (HCI_STP_TX == HCI_STP_TX_TASKLET) +#define HCI_STP_TX_TASKLET_RWLOCK (0) /* use rwlock_t */ +#define HCI_STP_TX_TASKLET_SPINLOCK (1) /* use spinlock_t */ + +/* select txq protection method */ +#define HCI_STP_TX_TASKLET_LOCK (HCI_STP_TX_TASKLET_SPINLOCK) +#endif + +#define HCI_STP_DEV_INIT_OPEN_CTX (0) /* do init in hci_dev->open context, checked ok */ +#define HCI_STP_DEV_INIT_THRD (1) /* do init in another thread context */ + +/* select init context */ +#define HCI_STP_DEV_INIT (HCI_STP_DEV_INIT_THRD) + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* debugging */ +#include +#include + +/* constant of kernel version */ +#include + +/* kthread APIs */ +#include + +#include +#include + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/* HCI-STP flag bits */ +#define HCI_STP_PROTO_SET (0) +/* HCI-STP flag TX states bits */ +#define HCI_STP_SENDING (1) +#define HCI_STP_TX_WAKEUP (2) + +#if (HCI_STP_DEV_INIT == HCI_STP_DEV_INIT_THRD) +#define HCI_STP_INIT_TO_MSEC (5000) /* required time to finish init sequence */ +#endif + +/* maximum delay required */ +#define BT_CMD_DELAY_MS_COMM (50) +#define BT_CMD_DELAY_MS_RESET (500) +#define BT_CMD_DELAY_SAFE_GUARD (20) /*(2)*/ + +/* HCI-STP safer hci_reset handling */ +#define HCI_STP_SAFE_RESET (1) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +struct hci_stp_init_cmd { + unsigned char *hci_cmd; + unsigned int cmdSz; + unsigned char *hci_evt; + unsigned int evtSz; + char *str; +}; + +struct hci_stp { + struct hci_dev *hdev; + unsigned long flags; + + struct sk_buff_head txq; /* used to queue TX packets */ + unsigned long tx_state; + +#if (HCI_STP_DEV_INIT == HCI_STP_DEV_INIT_THRD) + struct work_struct init_work; + struct completion *p_init_comp; + wait_queue_head_t *p_init_evt_wq; + spinlock_t init_lock; /* protect init variables: comp and wq */ + unsigned int init_cmd_idx; + int init_evt_rx_flag; /* init result of last sent cmd */ +#endif + +#if HCI_STP_SAFE_RESET + wait_queue_head_t reset_wq; + atomic_t reset_count; /* !0: reset in progress */ +#endif + //void *priv; /* unused? */ + //struct sk_buff *tx_skb; /* unused? */ + //spinlock_t rx_lock; /* unused? */ +}; + +struct btradio_conf_data { + unsigned char addr[6]; + unsigned char voice[2]; + unsigned char codec[4]; + unsigned char radio[6]; + unsigned char sleep[7]; + unsigned char feature[2]; + unsigned char tx_pwr_offset[3]; +}; +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +#define hci_stp_init_entry(c) {.hci_cmd=c, .cmdSz=sizeof(c), .hci_evt=c##_evt, .evtSz=sizeof(c##_evt), .str=#c} + +#endif /* end of _HCI_STP_H */ + diff --git a/drivers/mtk_wcn_combo/drv_bt/linux/hci_stp.c b/drivers/mtk_wcn_combo/drv_bt/linux/hci_stp.c new file mode 100755 index 000000000000..84c5e10ffe4b --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_bt/linux/hci_stp.c @@ -0,0 +1,1708 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* + * + * Bluetooth HCI UART driver + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +/* move compile flags to hci_stp.h file. */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "hci_stp.h" +#include "stp_exp.h" +#include "wmt_exp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/* Debugging Purpose */ +#define PFX "[HCI-STP]" +#define BT_LOG_LOUD (4) +#define BT_LOG_DBG (3) +#define BT_LOG_INFO (2) +#define BT_LOG_WARN (1) +#define BT_LOG_ERR (0) + +#define VERSION "1.0" +#define CUSTOM_BT_CFG_FILE "/data/BT.cfg" +#define INTERNAL_BT_CFG_FILE "/data/bluetooth/BT.cfg" +#define BUILTIN_BT_CFG_FILE "/system/etc/firmware/BT.cfg" + +/* H4 receiver States */ +#define H4_W4_PACKET_TYPE (0) +#define H4_W4_EVENT_HDR (1) +#define H4_W4_ACL_HDR (2) +#define H4_W4_SCO_HDR (3) +#define H4_W4_DATA (4) + +#define HCI_STP_TXQ_IN_BLZ (0) +/* access txq in BlueZ tx tasklet context */ +#define HCI_STP_TXQ_IN_HCISTP (1) +/* access txq in HCI-STP context, defined by compile flag: HCI_STP_TX */ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +unsigned int gHciStpDbgLevel = BT_LOG_ERR;//Modify loglevel + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +/* Allow one BT driver */ +static struct hci_dev *hdev = NULL; +static int reset = 0; + +/* maybe struct hci_stp is a better place to put these data */ +#if (HCI_STP_TX == HCI_STP_TX_TASKLET) +static struct tasklet_struct hci_tx_tasklet; + +#if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK) +static DEFINE_RWLOCK(hci_stp_txqlock); + +#elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK) +static spinlock_t hci_stp_txqlock; + +#endif +#endif + +#if (HCI_STP_TX == HCI_STP_TX_THRD) +static spinlock_t hci_stp_txqlock; +struct task_struct * hci_stp_tx_thrd = NULL; +wait_queue_head_t hci_stp_tx_thrd_wq; +#endif + +/* oringinal code path: +system/bluetooth/bluedroid/bluetooth.c +external/bluetooth/bluez/tools/hciattach.c +mtk/src/custom/mt6516_evb/kernel/core/src/board.c // set power gpio configuration +*/ +static unsigned char bt_bd_addr[10] = + {0x01, 0x1a, 0xfc, 0x06, 0x01, 0x20, 0x66, 0x46, 0x00, 0x00}; +static unsigned char bt_bd_addr_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x1a, 0xfc, 0x00}; +static unsigned char bt_link_key_type[5]= + {0x01, 0x1b, 0xfc, 0x01, 0x01}; +static unsigned char bt_link_key_type_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x1b, 0xfc, 0x00}; +static unsigned char bt_unit_key[20] = + {0x01, 0x75, 0xfc, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static unsigned char bt_unit_key_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x75, 0xfc, 0x00}; +static unsigned char bt_encrypt[7] = + {0x01, 0x76, 0xfc, 0x03, 0x00, 0x02, 0x10}; +static unsigned char bt_encrypt_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x76, 0xfc, 0x00}; +static unsigned char bt_pin_code_type[5] = + {0x01, 0x0a, 0x0c, 0x01, 0x00}; +static unsigned char bt_pin_code_type_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x0a, 0x0c, 0x00}; +static unsigned char bt_voice[6] = + {0x01, 0x26, 0x0c, 0x02, 0x60, 0x00}; +static unsigned char bt_voice_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x26, 0x0c, 0x00}; +static unsigned char bt_codec[8] = + {0x01, 0x72, 0xfc, 0x04, 0x23, 0x10, 0x00, 0x00}; +static unsigned char bt_codec_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x72, 0xfc, 0x00}; +static unsigned char bt_radio[10] = + {0x01, 0x79, 0xfc, 0x06, 0x06, 0x80, 0x00, 0x06, 0x03, 0x06}; +static unsigned char bt_radio_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x79, 0xfc, 0x00}; +static unsigned char bt_tx_pwr_offset[7] = + {0x01, 0x93, 0xfc, 0x03, 0xff, 0xff, 0xff}; +static unsigned char bt_tx_pwr_offset_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x93, 0xfc, 0x00}; +static unsigned char bt_sleep[11] = + {0x01, 0x7a, 0xfc, 0x07, 0x03, 0x40, 0x1f, 0x40, 0x1f, 0x00, 0x04}; +static unsigned char bt_sleep_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x7a, 0xfc, 0x00}; +static unsigned char bt_feature[6] = + {0x01, 0x7d, 0xfc, 0x02, 0x80, 0x0}; +static unsigned char bt_feature_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x7d, 0xfc, 0x00}; +static unsigned char bt_OSC[9] = + {0x01, 0x7b, 0xfc, 0x05, 0x01, 0x01, 0x14, 0x0a, 0x05}; +static unsigned char bt_OSC_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x7b, 0xfc, 0x00}; +static unsigned char bt_LPO[14] = + {0x01, 0x7c, 0xfc, 0x0a, 0x01, 0xfa, 0x0a, 0x02, 0x00, 0xa6, 0x0e, 0x00, 0x40, 0x00}; +static unsigned char bt_LPO_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x7c, 0xfc, 0x00}; +static unsigned char bt_legacy_PTA[14] = + {0x01, 0x74, 0xfc, 0x0a, 0xc9, 0x8b, 0xbf, 0x00, 0x00, 0x52, 0x0e, 0x0e, 0x1f, 0x1b}; +static unsigned char bt_legacy_PTA_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x74, 0xfc, 0x00}; +static unsigned char bt_BLE_PTA[9] = + {0x01, 0xfc, 0xfc, 0x05, 0x16, 0x0e, 0x0e, 0x00, 0x07}; +static unsigned char bt_BLE_PTA_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0xfc, 0xfc, 0x00}; +static unsigned char bt_RF_desence[10] = + {0x01, 0x20, 0xfc, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}; +static unsigned char bt_RF_desence_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x20, 0xfc, 0x00}; +static unsigned char bt_reset[4] = + {0x01, 0x03, 0x0c, 0x0}; +static unsigned char bt_reset_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0x03, 0x0c, 0x00}; +static unsigned char bt_intern_PTA_1[19] = + {0x01, 0xfb, 0xfc, 0x0f, 0x00, 0x01, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x01, 0x0f, 0x0f, 0x02, 0x01}; +static unsigned char bt_intern_PTA_1_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0xfb, 0xfc, 0x00}; +static unsigned char bt_intern_PTA_2[11] = + {0x01, 0xfb, 0xfc, 0x07, 0x01, 0x19, 0x19, 0x07, 0xd0, 0x00, 0x01}; +static unsigned char bt_intern_PTA_2_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0xfb, 0xfc, 0x00}; +static unsigned char bt_SLP_control_reg[12] = + {0x01, 0xd0, 0xfc, 0x08, 0x74, 0x00, 0x01, 0x81, 0xe2, 0x29, 0x0, 0x0}; +static unsigned char bt_SLP_control_reg_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0xd0, 0xfc, 0x00}; +static unsigned char bt_SLP_LDOD_reg[12] = + {0x01, 0xd0, 0xfc, 0x08, 0x1c, 0x00, 0x02, 0x81, 0x79, 0x08, 0x0, 0x0}; +static unsigned char bt_SLP_LDOD_reg_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0xd0, 0xfc, 0x00}; +static unsigned char bt_RF_reg[10] = + {0x01, 0xb0, 0xfc, 0x06, 0x64, 0x01, 0x02, 0x00, 0x00, 0x00}; +static unsigned char bt_RF_reg_evt[] = + {0x04, 0x0e, 0x04, 0x01, 0xb0, 0xfc, 0x00}; + +#if (HCI_STP_DEV_INIT == HCI_STP_DEV_INIT_THRD) +/* use this array to store received event content temporarily */ +static struct hci_stp_init_cmd init_table[] = +{ + /* do init in sequence, cmd and cmd##_evt array */ + hci_stp_init_entry(bt_bd_addr), + hci_stp_init_entry(bt_link_key_type), + hci_stp_init_entry(bt_unit_key), + hci_stp_init_entry(bt_encrypt), + hci_stp_init_entry(bt_pin_code_type), + hci_stp_init_entry(bt_voice), + hci_stp_init_entry(bt_codec), + hci_stp_init_entry(bt_radio), + hci_stp_init_entry(bt_tx_pwr_offset), + hci_stp_init_entry(bt_sleep), + hci_stp_init_entry(bt_feature), + hci_stp_init_entry(bt_OSC), + hci_stp_init_entry(bt_LPO), + hci_stp_init_entry(bt_legacy_PTA), + hci_stp_init_entry(bt_BLE_PTA), + hci_stp_init_entry(bt_RF_desence), + hci_stp_init_entry(bt_reset), + hci_stp_init_entry(bt_intern_PTA_1), + hci_stp_init_entry(bt_intern_PTA_2), + hci_stp_init_entry(bt_SLP_control_reg), + hci_stp_init_entry(bt_SLP_LDOD_reg), + hci_stp_init_entry(bt_RF_reg), +}; +#endif + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#define BT_LOUD_FUNC(fmt, arg...) if(gHciStpDbgLevel >= BT_LOG_LOUD){ printk(PFX "[L]%s:" fmt, __FUNCTION__ ,##arg);} +#define BT_DBG_FUNC(fmt, arg...) if(gHciStpDbgLevel >= BT_LOG_DBG){ printk(PFX "[D]%s:" fmt, __FUNCTION__ ,##arg);} +#define BT_INFO_FUNC(fmt, arg...) if(gHciStpDbgLevel >= BT_LOG_INFO){ printk(PFX "[I]%s:" fmt, __FUNCTION__ ,##arg);} +#define BT_WARN_FUNC(fmt, arg...) if(gHciStpDbgLevel >= BT_LOG_WARN){ printk(PFX "[W]%s:" fmt, __FUNCTION__ ,##arg);} +#define BT_ERR_FUNC(fmt, arg...) if(gHciStpDbgLevel >= BT_LOG_ERR){ printk(PFX "[E]%s:" fmt, __FUNCTION__ ,##arg);} +#define BT_TRC_FUNC(f) if(gHciStpDbgLevel >= BT_LOG_LOUD){printk(PFX "[T]%s:%d\n", __FUNCTION__, __LINE__);} + +#if HCI_STP_SAFE_RESET +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) +/* HCI_RESET bit definition in linux/include/net/bluetooth/hci.h since 2.6.39: + http://lxr.free-electrons.com/source/include/net/bluetooth/hci.h?v=2.6.39;a=arm +*/ +#define BT_GET_HDEV_RST_FG(hdev) (test_bit(HCI_RESET, &hdev->flags)) +#else +#define BT_GET_HDEV_RST_FG(hdev) (0) /* no HCI_RESET bit available */ +#endif +#endif + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +/* Functions to be implemted by all HCI_STP_TX_* methods */ +void hci_stp_tx_init (struct hci_stp *hu); +void hci_stp_tx_deinit (struct hci_stp *hu); +void hci_stp_txq_lock (unsigned int ctx); +void hci_stp_txq_unlock (unsigned int ctx); +void hci_stp_tx_kick (void); + +/* Functions to be implemented by all HCI_STP_INIT_* methods*/ +static int hci_stp_dev_init (struct hci_stp *phu); + +#if (HCI_STP_TX == HCI_STP_TX_TASKLET) +static int hci_stp_tx_wakeup (struct hci_stp *hu); +static void hci_stp_tx_tasklet_func (unsigned long data); +#endif + +#if (HCI_STP_TX == HCI_STP_TX_THRD) +static int hci_stp_tx_thrd_func (void *pdata); +#endif + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +static inline void hci_stp_tx_skb_comp (struct hci_stp *hu, struct sk_buff *skb) +{ + struct hci_dev *hdev; + int pkt_type; + + + hdev = hu->hdev; + hdev->stat.byte_tx += skb->len; + + pkt_type = bt_cb(skb)->pkt_type; + /* Update HCI stat counters */ + switch (pkt_type) { + case HCI_COMMAND_PKT: + hdev->stat.cmd_tx++; + break; + + case HCI_ACLDATA_PKT: + hdev->stat.acl_tx++; + break; + + case HCI_SCODATA_PKT: + hdev->stat.cmd_tx++; + break; + } +} + +#if (HCI_STP_TX == HCI_STP_TX_TASKLET) +void hci_stp_tx_init (struct hci_stp *hu) +{ + tasklet_init(&hci_tx_tasklet, hci_stp_tx_tasklet_func, (unsigned long)hu); + + #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK) + rwlock_init(&hci_stp_txqlock); + #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK) + spin_lock_init(&hci_stp_txqlock); + #endif +} + +void hci_stp_tx_deinit (struct hci_stp *hu) +{ + tasklet_kill(&hci_tx_tasklet); + + return; +} + +void hci_stp_txq_lock (unsigned int ctx) +{ + if (ctx == HCI_STP_TXQ_IN_BLZ) { + /* lock txq in BlueZ tx tasklet context */ + #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK) + write_lock_bh(&hci_stp_txqlock); + #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK) + spin_lock_bh(&hci_stp_txqlock); + #else + #error "HCI_STP_TX_TASKLET_LOCK" + #endif + } + else { + /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */ + #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK) + write_lock_bh(&hci_stp_txqlock); + #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK) + spin_lock_bh(&hci_stp_txqlock); + #else + #error "HCI_STP_TX_TASKLET_LOCK" + #endif + } +} + +void hci_stp_txq_unlock (unsigned int ctx) +{ + if (ctx == HCI_STP_TXQ_IN_BLZ) { + /* lock txq in BlueZ tx tasklet context with hci_stp_tx */ + #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK) + write_unlock_bh(&hci_stp_txqlock); + #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK) + spin_unlock_bh(&hci_stp_txqlock); + #else + #error "HCI_STP_TX_TASKLET_LOCK" + #endif + } + else { + /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */ + #if (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_RWLOCK) + write_unlock_bh(&hci_stp_txqlock); + #elif (HCI_STP_TX_TASKLET_LOCK == HCI_STP_TX_TASKLET_SPINLOCK) + spin_unlock_bh(&hci_stp_txqlock); + #else + #error "HCI_STP_TX_TASKLET_LOCK" + #endif + } +} + +void hci_stp_tx_kick (void) +{ + tasklet_schedule(&hci_tx_tasklet); +} + +static void hci_stp_tx_tasklet_func(unsigned long data) { + + struct hci_stp *hu = (struct hci_stp *)data; + + /* sanity check to see if status is still correct? */ + if (unlikely(hdev == NULL)) { + BT_ERR_FUNC("Null hdev!\n"); + BUG_ON(hdev == NULL); + return; + } + + if (unlikely(hu != hdev->driver_data)) { + BT_ERR_FUNC("hu(0x%p) != hdev->driver_data(0x%p)\n", + hu, hdev->driver_data); + BUG_ON(hu != hdev->driver_data); + return; + } + + //read_lock(&hci_stp_txq_lock); + hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP); + + hci_stp_tx_wakeup(hu); + + //read_unlock(&hci_stp_txq_lock); + hci_stp_txq_unlock(HCI_STP_TXQ_IN_HCISTP); +} + +/* George: HCI_STP_SENDING and HCI_STP_TX_WAKEUP flags in this function seem +* to be redundant. +*/ +static int hci_stp_tx_wakeup(struct hci_stp *hu) +{ +// struct hci_dev *hdev = hu->hdev; + struct sk_buff *skb; + int j = 0; + + BT_TRC_FUNC(); + + if (test_and_set_bit(HCI_STP_SENDING, &hu->tx_state)) { + set_bit(HCI_STP_TX_WAKEUP, &hu->tx_state); + printk("[BT] enqueue and return\n"); + return 0; + } + + BT_DBG_FUNC("hci_stp_tx_wakeup %d\n", __LINE__); + +restart: + clear_bit(HCI_STP_TX_WAKEUP, &hu->tx_state); + + while ((skb = skb_dequeue(&hu->txq))) { + int len; + BT_DBG_FUNC("dqueue times = %d\n", ++j); + + /* hci reset cmd check */ +#if HCI_STP_SAFE_RESET + if (unlikely(skb->len == ARRAY_SIZE(bt_reset))) { + if (unlikely(!memcmp(bt_reset, skb->data, ARRAY_SIZE(bt_reset)))) { + atomic_inc(&hu->reset_count); + BT_DBG_FUNC("hci reset cmd,f(%d),c(%d)\n", + BT_GET_HDEV_RST_FG(hdev), + atomic_read(&hu->reset_count)); + } + } +#endif + + if ((len = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX)) == 0 ) { + /* can not send */ + BT_ERR_FUNC("mtk_wcn_stp_send_data can not send\n"); + BT_ERR_FUNC("Error %s %d\n", __FUNCTION__, __LINE__); + + skb_queue_head(&hu->txq, skb);//Put back to queue head + goto END; + } + + //hdev->stat.byte_tx += len; // moved into hci_stp_tx_skb_comp() + //hci_stp_tx_skb_comp(hu, bt_cb(skb)->pkt_type); + hci_stp_tx_skb_comp(hu, skb); + kfree_skb(skb); + } + +END: + if (test_bit(HCI_STP_TX_WAKEUP, &hu->tx_state)) + goto restart; + + clear_bit(HCI_STP_SENDING, &hu->tx_state); + + return 0; +} + + +#elif (HCI_STP_TX == HCI_STP_TX_THRD) + +void hci_stp_tx_init (struct hci_stp *hu) +{ + BT_DBG_FUNC("start:0x%p\n", hu); + + spin_lock_init(&hci_stp_txqlock); + init_waitqueue_head(&hci_stp_tx_thrd_wq); + + hci_stp_tx_thrd = kthread_create(hci_stp_tx_thrd_func, (void *)hu, "hci_stpd"); + if (NULL == hci_stp_tx_thrd) { + BT_ERR_FUNC("kthread_create hci_stpd fail!\n"); + } + wake_up_process(hci_stp_tx_thrd); + + BT_DBG_FUNC("done\n"); + return; +} + +void hci_stp_tx_deinit (struct hci_stp *hu) +{ + BT_DBG_FUNC("start:0x%p\n", hu); + + kthread_stop(hci_stp_tx_thrd); + hci_stp_tx_thrd = NULL; + + BT_DBG_FUNC("done\n"); + return; +} + +void hci_stp_txq_lock (unsigned int ctx) +{ + if (ctx == HCI_STP_TXQ_IN_BLZ) { + /* lock txq in BlueZ tx tasklet context */ + spin_lock(&hci_stp_txqlock); + } + else { + /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */ + spin_lock_bh(&hci_stp_txqlock); + } +} + +void hci_stp_txq_unlock (unsigned int ctx) +{ + if (ctx == HCI_STP_TXQ_IN_BLZ) { + spin_unlock(&hci_stp_txqlock); + } + else { + /* lock txq in HCI-STP context(defined by compile flag: HCI_STP_TX) */ + spin_unlock_bh(&hci_stp_txqlock); + } +} + +static int +hci_stp_tx_thrd_func (void *pdata) +{ + struct hci_stp *hu; + struct hci_dev *hdev; + struct sk_buff *skb; + int len; + + hu = (struct hci_stp *)pdata; + hdev = hu->hdev; + + /* sanity check to see if status is still correct? */ + if (unlikely(hdev == NULL)) { + BT_ERR_FUNC("Null hdev!\n"); + BUG_ON(hdev == NULL); + return -1; + } + + if (unlikely(hu != hdev->driver_data)) { + BT_ERR_FUNC("hu(0x%p) != hdev->driver_data(0x%p)\n", + hu, hdev->driver_data); + BUG_ON(hu != hdev->driver_data); + return -1; + } + + smp_mb(); /* sync shared data */ + + for (;;) { + wait_event_interruptible(hci_stp_tx_thrd_wq, + (!skb_queue_empty(&hu->txq) || kthread_should_stop())); + + if (unlikely(kthread_should_stop())) { + BT_INFO_FUNC("hci_stpd thread should stop now... \n"); + break; + } + + hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP); + while ((skb = skb_dequeue(&hu->txq))) { + /* protect txq only */ + hci_stp_txq_unlock(HCI_STP_TXQ_IN_HCISTP); + + /* hci reset cmd check */ + #if HCI_STP_SAFE_RESET + if (unlikely(skb->len == ARRAY_SIZE(bt_reset))) { + if (unlikely(!memcmp(bt_reset, skb->data, ARRAY_SIZE(bt_reset)))) { + atomic_inc(&hu->reset_count); + BT_DBG_FUNC("hci reset cmd,f(%d),c(%d)\n", + BT_GET_HDEV_RST_FG(hdev), + atomic_read(&hu->reset_count)); + } + } + #endif + + len = mtk_wcn_stp_send_data(skb->data, skb->len, BT_TASK_INDX); + if (unlikely(len != skb->len)) { + /* can not send */ + BT_ERR_FUNC("mtk_wcn_stp_send_data fail, enqueue again!(%d, %d)\n", + len, skb->len); + + hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP); + skb_queue_head(&hu->txq, skb);//Put back to queue head + /* do hci_stp_txq_unlock outside while loop */ + break; + } + //hdev->stat.byte_tx += len; // moved into hci_stp_tx_skb_comp() + hci_stp_tx_skb_comp(hu, skb); + kfree_skb(skb); + + hci_stp_txq_lock(HCI_STP_TXQ_IN_HCISTP); + } + hci_stp_txq_unlock(HCI_STP_TXQ_IN_HCISTP); + + /* back to wait */ + } + + BT_INFO_FUNC("hci_stpd stop!\n"); + return 0; +} + +void hci_stp_tx_kick (void) +{ + wake_up_interruptible(&hci_stp_tx_thrd_wq); +} + +#else +#error "Not implemented HCI_STP_TX" +#endif + +#if (HCI_STP_DEV_INIT == HCI_STP_DEV_INIT_OPEN_CTX) +static int hci_stp_dev_init (struct hci_stp *phu) +{ + BT_INFO_FUNC("Reset bd_addr =>\n"); + mtk_wcn_stp_send_data(bt_bd_addr, 10, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bd_addr <=\n"); + + BT_INFO_FUNC("Reset bt_link_key_type =>\n"); + mtk_wcn_stp_send_data(bt_link_key_type, 5, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_link_key_type <=\n"); + + BT_INFO_FUNC("Reset bt_unit_key =>\n"); + mtk_wcn_stp_send_data(bt_unit_key, 20, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_unit_key <=\n"); + + BT_INFO_FUNC("Reset bt_encrypt =>\n"); + mtk_wcn_stp_send_data(bt_encrypt, 7, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_encrypt <=\n"); + + BT_INFO_FUNC("Reset bt_pin_code_type =>\n"); + mtk_wcn_stp_send_data(bt_pin_code_type, 5, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_pin_code_type <=\n"); + + BT_INFO_FUNC("Reset bt_voice =>\n"); + mtk_wcn_stp_send_data(bt_voice, 6, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_voice <=\n"); + + BT_INFO_FUNC("Reset bt_codec =>\n"); + mtk_wcn_stp_send_data(bt_codec, 8, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_codec <=\n"); + + BT_INFO_FUNC("Reset bt_radio =>\n"); + mtk_wcn_stp_send_data(bt_radio, 10, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_radio <=\n"); + + BT_INFO_FUNC("Reset bt_tx_pwr_offset =>\n"); + mtk_wcn_stp_send_data(bt_tx_pwr_offset, 7, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_tx_pwr_offset <=\n"); + + BT_INFO_FUNC("Reset bt_sleep =>\n"); + mtk_wcn_stp_send_data(bt_sleep, 11, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_sleep <=\n"); + + BT_INFO_FUNC("Reset bt_feature =>\n"); + mtk_wcn_stp_send_data(bt_feature, 6, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_feature <=\n"); + + BT_INFO_FUNC("Reset bt_OSC =>\n"); + mtk_wcn_stp_send_data(bt_OSC, 9, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_OSC <=\n"); + + BT_INFO_FUNC("Reset bt_LPO =>\n"); + mtk_wcn_stp_send_data(bt_LPO, 14, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_LPO <=\n"); + + BT_INFO_FUNC("Reset bt_legacy_PTA =>\n"); + mtk_wcn_stp_send_data(bt_legacy_PTA, 14, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_legacy_PTA <=\n"); + + BT_INFO_FUNC("Reset bt_BLE_PTA =>\n"); + mtk_wcn_stp_send_data(bt_BLE_PTA, 9, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_BLE_PTA <=\n"); + + BT_INFO_FUNC("Reset bt_RF_desence =>\n"); + mtk_wcn_stp_send_data(bt_RF_desence, 10, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_RF_desence <=\n"); + + BT_INFO_FUNC("Reset bt_reset =>\n"); + mtk_wcn_stp_send_data(bt_reset, 4, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_RESET); + BT_INFO_FUNC("Reset bt_reset <=\n"); + + BT_INFO_FUNC("Reset bt_intern_PTA_1 =>\n"); + mtk_wcn_stp_send_data(bt_intern_PTA_1, 19, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_intern_PTA_1 <=\n"); + + BT_INFO_FUNC("Reset bt_intern_PTA_2 =>\n"); + mtk_wcn_stp_send_data(bt_intern_PTA_2, 11, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_intern_PTA_2 <=\n"); + + BT_INFO_FUNC("Reset bt_SLP_control_reg =>\n"); + mtk_wcn_stp_send_data(bt_SLP_control_reg, 12, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_SLP_control_reg <=\n"); + + BT_INFO_FUNC("Reset bt_SLP_LDOD_reg =>\n"); + mtk_wcn_stp_send_data(bt_SLP_LDOD_reg, 12, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_SLP_LDOD_reg <=\n"); + + BT_INFO_FUNC("Reset bt_RF_reg =>\n"); + mtk_wcn_stp_send_data(bt_RF_reg, 10, BT_TASK_INDX); + msleep(BT_CMD_DELAY_MS_COMM); + BT_INFO_FUNC("Reset bt_RF_reg <=\n"); + + return 0; +} + +#elif (HCI_STP_DEV_INIT == HCI_STP_DEV_INIT_THRD) + +void hci_stp_dev_init_rx_cb (const UINT8 *data, INT32 count) +{ + struct hci_stp *hu; + unsigned int idx; + + if (unlikely(!hdev)) { + BT_ERR_FUNC("null hdev!\n"); + return; + } + if (unlikely(!hdev->driver_data)) { + BT_ERR_FUNC("null hdev->driver_data!\n"); + return; + } + + /* get hci_stp from global variable */ + hu = (struct hci_stp *)hdev->driver_data; + idx = hu->init_cmd_idx; + + if (unlikely(count != init_table[idx].evtSz)) { + hu->init_evt_rx_flag = -1; /* size mismatch */ + } + else if (unlikely(memcmp(data, init_table[idx].hci_evt, count))) { + hu->init_evt_rx_flag = -2; /* content mismatch */ + } + else { + hu->init_evt_rx_flag = 1; /* ok */ + BT_DBG_FUNC("EVT i(%d),rx(%d) ok\n", idx, count); + } + + if (unlikely(1 != hu->init_evt_rx_flag)) { + int i; + BT_WARN_FUNC("EVT i(%d),rx(%d)buf:[", idx, count); + for (i = 0; i < count; ++i) { + printk("0x%02x ", data[i]); + } + printk("]\n"); + BT_WARN_FUNC("EVT i(%d),exp(%d)buf:[", idx, init_table[idx].evtSz); + for (i = 0; i < count; ++i) { + printk("0x%02x ", init_table[idx].hci_evt[i]); + } + printk("]\n"); + + } + + smp_mb(); /* sync shared data */ + wake_up(hu->p_init_evt_wq); /* wake up dev_init_work */ +} + +static void hci_stp_dev_init_work (struct work_struct *work) +{ + struct hci_stp *phu; + unsigned int idx; + long ret; + long to; + + BT_DBG_FUNC("++\n"); + + /* get client's information */ + phu = container_of(work, struct hci_stp, init_work); + + for (idx = 0; idx < ARRAY_SIZE(init_table); ++idx) { + phu->init_cmd_idx = idx; + phu->init_evt_rx_flag = 0; + to = (init_table[idx].hci_cmd == bt_reset) ? BT_CMD_DELAY_MS_RESET : BT_CMD_DELAY_MS_COMM; + /* safe waiting time in case running on a busy system */ + to = msecs_to_jiffies(to * BT_CMD_DELAY_SAFE_GUARD); + + BT_DBG_FUNC("CMD(%d),(%s),t/o(%ld))=>\n", idx, init_table[idx].str, to); + smp_wmb(); /* sync shared data */ + + /* Send hci command */ + mtk_wcn_stp_send_data(init_table[idx].hci_cmd, init_table[idx].cmdSz, BT_TASK_INDX); + /* Wait rx hci event */ + /* no need to lock init_lock here for wq, for that it will be freed + * only after we call complete(phu->p_init_comp); in this function. + */ + ret = wait_event_timeout((*phu->p_init_evt_wq), phu->init_evt_rx_flag != 0, to); + + /* Check result */ + if (likely(1 == phu->init_evt_rx_flag)) { + BT_DBG_FUNC("EVT(%d) ret(%u) ok<=\n", idx, jiffies_to_msecs(ret)); + /* process next cmd */ + continue; + } + else { + BT_WARN_FUNC("EVT(%d) ret(%u) to(%ld) fg(%d)<=\n", + idx, jiffies_to_msecs(ret), to, phu->init_evt_rx_flag); + /* stop processing and skip next cmd */ + break; + } + } + + if (phu->p_init_comp) { + complete(phu->p_init_comp); + } + + BT_DBG_FUNC("--\n"); +} + +static int hci_stp_dev_init (struct hci_stp *phu) +{ + DECLARE_COMPLETION_ONSTACK(hci_stp_dev_init_comp); + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(hci_stp_dev_init_wq); + + spin_lock(&phu->init_lock); + phu->p_init_comp = &hci_stp_dev_init_comp; + phu->p_init_evt_wq = &hci_stp_dev_init_wq; + spin_unlock(&phu->init_lock); + + /* unregister rx event callback */ + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); + /* register direct rx callback for init only */ + mtk_wcn_stp_register_if_rx(hci_stp_dev_init_rx_cb); + /* use bluez mode */ + mtk_wcn_stp_set_bluez(1); + + /* Schedule to call hci_stp_dev_init_work(). init_work is initialized in + * hci_stp_init(). + */ + schedule_work(&phu->init_work); + + //ret = wait_for_completion_interruptible_timeout(&hci_stp_dev_init_comp, msecs_to_jiffies(HCI_STP_INIT_TO_MSEC)); /* 3 seconds? */ + wait_for_completion(&hci_stp_dev_init_comp); + + spin_lock(&phu->init_lock); + /* clear references to stack variables */ + phu->p_init_comp = NULL; + phu->p_init_evt_wq = NULL; + spin_unlock(&phu->init_lock); + + /* check result */ + /* flag: (to be replaced by a constant value) + 1 rx event correctly, + 0 no response in time, + -1 unequal rx event length, + -2 unequal rx event content. + */ + if (likely(1 == phu->init_evt_rx_flag)) { + return 0; + } + else { + /* return non-zero value for error */ + return (phu->init_evt_rx_flag + 256); + } +} +#else +#error "Not implemented HCI_STP_DEV_INIT" +#endif + + +static ssize_t file_read(char *filename, char *buf, size_t len, loff_t *offset) +{ + struct file *fp; + mm_segment_t old_fs; + ssize_t retLen; + + fp = filp_open(filename, O_RDONLY, 0); + if (IS_ERR(fp)) { + BT_ERR_FUNC("Failed to open %s!\n", filename); + return -1; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + if ((fp->f_op == NULL) || (fp->f_op->read == NULL)){ + BT_ERR_FUNC("File can not be read!\n"); + set_fs(old_fs); + filp_close(fp, NULL); + return -1; + } + + retLen = fp->f_op->read(fp, buf, len, offset); + + set_fs(old_fs); + filp_close(fp, NULL); + + return retLen; +} + +static ssize_t file_write(char *filename, char *buf, size_t len, loff_t *offset) +{ + struct file *fp; + mm_segment_t old_fs; + ssize_t retLen; + + fp = filp_open(filename, O_WRONLY | O_CREAT, 0644); + if (IS_ERR(fp)) { + BT_ERR_FUNC("Failed to open %s!\n", filename); + return -1; + } + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + if ((fp->f_op == NULL) || (fp->f_op->write == NULL)){ + BT_ERR_FUNC("File can not be write!\n"); + set_fs(old_fs); + filp_close(fp, NULL); + return -1; + } + + retLen = fp->f_op->write(fp, buf, len, offset); + + set_fs(old_fs); + filp_close(fp, NULL); + + return retLen; +} + +int load_custom_bt_conf(struct btradio_conf_data *cfg) +{ + /* + This method depends on customer's platform configuration data + store machenism. + Customer may use NVRAM, data file, or other patterns. + Here RECOMMEND and GIVE AN EXAMPLE to push configuration data + under /data/BT.cfg + */ + + struct btradio_conf_data temp; + loff_t pos = 0; + ssize_t retLen; + + retLen = file_read(CUSTOM_BT_CFG_FILE, + (char*)&temp, + sizeof(temp), + &pos); + + if (retLen < 0) + return -1; + + if(retLen < sizeof(temp)){ + BT_ERR_FUNC("File read length error %d\n", retLen); + return -1; + } + + memcpy(cfg, &temp, retLen); + + return 0; +} + +int load_internal_bt_conf(struct btradio_conf_data *cfg) +{ + struct btradio_conf_data temp; + loff_t pos = 0; + ssize_t retLen; + ssize_t written; + + // default BD_ADDR + unsigned char addr[6] = {0x00, 0x00, 0x46, 0x66, 0x20, 0x01}; + unsigned long randNum; + + retLen = file_read(INTERNAL_BT_CFG_FILE, + (char*)&temp, + sizeof(temp), + &pos); + + if (retLen < 0){ + BT_INFO_FUNC("No internal BT config file, generate from built-in BT config\n"); + + pos = 0; + retLen = file_read(BUILTIN_BT_CFG_FILE, + (char*)&temp, + sizeof(temp), + &pos); + if (retLen < 0){ + BT_ERR_FUNC("Try to read built-in BT config, error\n"); + return -1; + } + else if(retLen < sizeof(temp)){ + BT_ERR_FUNC("File read length error %d\n", retLen); + return -1; + } + + if (0 == memcmp(temp.addr, addr, 6)){ + BT_DBG_FUNC("Built-in config use default BD address, enable auto-gen mechanism!\n"); + get_random_bytes(&randNum, sizeof(unsigned long)); + BT_DBG_FUNC("Get random number: %lu\n", randNum); + + temp.addr[0] = (((randNum>>24 | randNum>>16) & (0xFE)) | (0x02)); + temp.addr[1] = ((randNum>>8) & 0xFF); + temp.addr[5] = (randNum & 0xFF); + + // Generate internal BT config file + pos = 0; + written = file_write(INTERNAL_BT_CFG_FILE, + (char*)&temp, + sizeof(temp), + &pos); + if (written < 0){ + BT_ERR_FUNC("Try to create internal BT config, error\n"); + } + else if(written < sizeof(temp)){ + BT_ERR_FUNC("File write length error %d\n", written); + } + else{ + BT_INFO_FUNC("Internal BT config generated\n"); + } + } + } + else if(retLen < sizeof(temp)){ + BT_ERR_FUNC("File read length error %d\n", retLen); + return -1; + } + + memcpy(cfg, &temp, retLen); + + return 0; +} + +/* Invoked when there is ONE received BT packet */ +void stp_tx_event_cb(void) +{ +#if 0 + struct hci_stp *hu; + if (unlikely(hdev == NULL)) { + BT_ERR_FUNC("Null hdev!\n"); + BUG_ON(hdev == NULL); + return; + } + hu = (struct hci_stp *) hdev->driver_data; +#endif + /* George: [FixMe] can we call hci_stp_tx_wakeup() directly in STP-CORE's + * context? It seems to be dangerous! Replace it with suitable one according + * to HCI_STP_TX compile flag. + */ + hci_stp_tx_kick(); /* George: adapt different tx_kick function */ +} + +/* + Direct delivery of bluez not changed hands through the stp buffer +*/ +void stp_rx_event_cb_directly(const UINT8 *data, INT32 count) +{ + register const UINT8 *ptr; + struct hci_event_hdr *eh; + struct hci_acl_hdr *ah; + struct hci_sco_hdr *sh; + register int len, type, dlen; + int while_count; /* = 0; Is while_count redundant? */ + //static unsigned long rx_count; /* Is it ok w/o an initial value??? */ + static unsigned int rx_count = 0; + //static unsigned long rx_state; /* Is it ok w/o an initial value??? */ + static unsigned int rx_state = H4_W4_PACKET_TYPE; + struct sk_buff *rx_skb = NULL; /* Is it ok to use non-static skb??? */ + register int room; +#if HCI_STP_SAFE_RESET + struct hci_stp *hu; +#endif + + BT_LOUD_FUNC("count(%d)rx_state(%d)rx_count(%d)\n", + count, rx_state, rx_count); + + if (data == NULL) { + BT_ERR_FUNC("Data is Null\n"); + return; + } + + if (count > 5000) { + BT_WARN_FUNC("abnormal count(%d)\n", count); + } + + ptr = data; + /*Add statistic*/ + hdev->stat.byte_rx += count; + +#if HCI_STP_SAFE_RESET + hu = (struct hci_stp *)hdev->driver_data; + /* is waiting hci reset event? */ + if (unlikely(atomic_read(&hu->reset_count))) { + if (count == ARRAY_SIZE(bt_reset_evt)) { + if (!memcmp(bt_reset_evt, data, ARRAY_SIZE(bt_reset_evt))) { + BT_DBG_FUNC("hci reset evt,f(%d),c(%d)\n", + BT_GET_HDEV_RST_FG(hdev), + atomic_read(&hu->reset_count)); + + atomic_dec(&hu->reset_count); + wake_up(&hu->reset_wq); + } + } + } +#endif + + while_count = 0; + while (count > 0) { /* while (count) */ + /* Is while_count redundant? */ + //while_count++; + if (++while_count > 5000) { + BT_WARN_FUNC("abnormal while_count(%d)\n", while_count); + } + + if (rx_count) { + len = min_t(unsigned int, rx_count, count); + memcpy(skb_put(rx_skb, len), ptr, len); + rx_count -= len; + count -= len; + ptr += len; + + if (rx_count) + continue; + /* rx_count==0, ready to indicate to hci_core */ + + switch (rx_state) { + case H4_W4_DATA: + BT_LOUD_FUNC("Complete data\n"); + hci_recv_frame(rx_skb); + rx_state = H4_W4_PACKET_TYPE; + rx_skb = NULL; + continue; + + case H4_W4_EVENT_HDR: + eh = hci_event_hdr(rx_skb); + //BT_DBG_FUNC("Event header:evt(0x%2.2x)plen(%d)\n", eh->evt, eh->plen); + room = skb_tailroom(rx_skb); + //BT_DBG_FUNC("len(%d)room(%d)\n", eh->plen, room); + BT_LOUD_FUNC("Event header:evt(0x%2.2x)plen(%d)room(%d)\n", + eh->evt, eh->plen, room); + + if (!eh->plen) { + hci_recv_frame(rx_skb); + rx_state = H4_W4_PACKET_TYPE; + rx_skb = NULL; + rx_count = 0; /* redundant? here rx_count is 0 already */ + } + else if (eh->plen > room) { + //BT_ERR("Data length is too large\n"); + BT_ERR_FUNC("too large data length:eh->plen(%d)>room(%d)\n", + eh->plen, room); + kfree_skb(rx_skb); + rx_state = H4_W4_PACKET_TYPE; + rx_skb = NULL; + rx_count = 0; /* redundant? here rx_count is 0 already */ + } + else { + rx_state = H4_W4_DATA; + rx_count = eh->plen; + } + continue; + + case H4_W4_ACL_HDR: + ah = hci_acl_hdr(rx_skb); + dlen = __le16_to_cpu(ah->dlen); + + room = skb_tailroom(rx_skb); + BT_LOUD_FUNC("ACL header:dlen(%d)room(%d)\n", dlen, room); + if (!dlen) { + hci_recv_frame(rx_skb); + rx_state = H4_W4_PACKET_TYPE; + rx_skb = NULL; + rx_count = 0; + } + else if (dlen > room) { + //BT_ERR_FUNC("Data length is too large\n"); + BT_ERR_FUNC("too large data length:dlen(%d)>room(%d)\n", + dlen, room); + kfree_skb(rx_skb); + rx_state = H4_W4_PACKET_TYPE; + rx_skb = NULL; + rx_count = 0; + } + else { + rx_state = H4_W4_DATA; + rx_count = dlen; + } + continue; + + case H4_W4_SCO_HDR: + sh = hci_sco_hdr(rx_skb); + room = skb_tailroom(rx_skb); + BT_LOUD_FUNC("SCO header:dlen(%d)room(%d)\n", sh->dlen, room); + + if (!sh->dlen) { + hci_recv_frame(rx_skb); + rx_state = H4_W4_PACKET_TYPE; + rx_skb = NULL; + rx_count = 0; + } + else if (sh->dlen > room) { + BT_ERR_FUNC("Data length is too large\n"); + BT_ERR_FUNC("too large data length:sh->dlen(%d)>room(%d)\n", + sh->dlen , room); + kfree_skb(rx_skb); + rx_state = H4_W4_PACKET_TYPE; + rx_skb = NULL; + rx_count = 0; + } + else { + rx_state = H4_W4_DATA; + rx_count = sh->dlen; + } + continue; + } + } + + /* H4_W4_PACKET_TYPE */ + switch (*ptr) { + case HCI_EVENT_PKT: + BT_LOUD_FUNC("Event packet\n"); + rx_state = H4_W4_EVENT_HDR; + rx_count = HCI_EVENT_HDR_SIZE; + type = HCI_EVENT_PKT; + break; + + case HCI_ACLDATA_PKT: + BT_LOUD_FUNC("ACL packet\n"); + rx_state = H4_W4_ACL_HDR; + rx_count = HCI_ACL_HDR_SIZE; + type = HCI_ACLDATA_PKT; + break; + + case HCI_SCODATA_PKT: + BT_LOUD_FUNC("SCO packet\n"); + rx_state = H4_W4_SCO_HDR; + rx_count = HCI_SCO_HDR_SIZE; + type = HCI_SCODATA_PKT; + break; + + default: + BT_ERR_FUNC("Unknown HCI packet type %2.2x\n", (__u8)*ptr); + ++(hdev->stat.err_rx); + ++ptr; + --count; + continue; + }; + + ++ptr; + --count; + + /* Allocate packet */ + rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC); + if (!rx_skb) { + BT_ERR_FUNC("bt_skb_alloc(%d, GFP_ATOMIC) fail!\n", HCI_MAX_FRAME_SIZE); + rx_state = H4_W4_PACKET_TYPE; + rx_count = 0; + return; + } + + rx_skb->dev = (void *) hdev; + bt_cb(rx_skb)->pkt_type = type; + } + + return; +} + +/* ------- Interface to HCI layer ------ */ +/* Initialize device */ +static int hci_stp_open(struct hci_dev *hdev) +{ + struct hci_stp *hu; + struct btradio_conf_data cfg; + int ret; + + if (unlikely(!hdev)) { + BT_ERR_FUNC("null hdev\n"); + return -ENODEV; + } + + if (unlikely(!hdev->driver_data)) { + BT_ERR_FUNC("null hdev\n"); + return -ENODEV; + } + + hu = (struct hci_stp *)hdev->driver_data; + BT_INFO_FUNC("%s(0x%p)\n", hdev->name, hdev); + + /* clear txq and free all skb in it */ + hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ); + skb_queue_purge(&hu->txq); + hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ); + + /* turn on BT */ + if (unlikely(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"); + + if (likely(mtk_wcn_stp_is_ready())) { + + BT_LOUD_FUNC("STP is ready!\n"); + + memset(&cfg, 0, sizeof(struct btradio_conf_data)); + if (load_custom_bt_conf(&cfg) < 0){ + BT_INFO_FUNC("No custom BT config\n"); + + if (load_internal_bt_conf(&cfg) < 0){ + BT_ERR_FUNC("Load internal BT config failed!\n"); + goto init_start; + } + else{ + BT_INFO_FUNC("Load internal BT config success\n"); + } + } + else{ + BT_INFO_FUNC("Load custom BT config success\n"); + } +#if 1 /* refine output format */ + BT_DBG_FUNC("Read BT config data:\n"); + BT_DBG_FUNC("[BD addr %02x-%02x-%02x-%02x-%02x-%02x]\n", + cfg.addr[0], cfg.addr[1], cfg.addr[2], cfg.addr[3], cfg.addr[4], cfg.addr[5]); + BT_DBG_FUNC("[voice %02x %02x][codec %02x %02x %02x %02x]\n", + cfg.voice[0], cfg.voice[1], + cfg.codec[0], cfg.codec[1], cfg.codec[2], cfg.codec[3]); + BT_DBG_FUNC("[radio %02x %02x %02x %02x %02x %02x]\n", + cfg.radio[0], cfg.radio[1], cfg.radio[2], cfg.radio[3], cfg.radio[4], cfg.radio[5]); + BT_DBG_FUNC("[sleep %02x %02x %02x %02x %02x %02x %02x]\n", + cfg.sleep[0], cfg.sleep[1], cfg.sleep[2], cfg.sleep[3], cfg.sleep[4], cfg.sleep[5], cfg.sleep[6]); + BT_DBG_FUNC("[feature %02x %02x][tx power offset %02x %02x %02x]\n", + cfg.feature[0], cfg.feature[1], + cfg.tx_pwr_offset[0], cfg.tx_pwr_offset[1], cfg.tx_pwr_offset[2]); +#else + BT_DBG_FUNC("Read BT config data: [BD addr %02x-%02x-%02x-%02x-%02x-%02x][voice %02x %02x] \ + [codec %02x %02x %02x %02x][radio %02x %02x %02x %02x %02x %02x] \ + [sleep %02x %02x %02x %02x %02x %02x %02x][feature %02x %02x] \ + [tx power offset %02x %02x %02x]\n", + cfg.addr[0], cfg.addr[1], cfg.addr[2], cfg.addr[3], cfg.addr[4], cfg.addr[5], + cfg.voice[0], cfg.voice[1], cfg.codec[0], cfg.codec[1], cfg.codec[2], cfg.codec[3], + cfg.radio[0], cfg.radio[1], cfg.radio[2], cfg.radio[3], cfg.radio[4], cfg.radio[5], + cfg.sleep[0], cfg.sleep[1], cfg.sleep[2], cfg.sleep[3], cfg.sleep[4], cfg.sleep[5], cfg.sleep[6], + cfg.feature[0], cfg.feature[1], + cfg.tx_pwr_offset[0], cfg.tx_pwr_offset[1], cfg.tx_pwr_offset[2]); +#endif + bt_bd_addr[4] = cfg.addr[5]; + bt_bd_addr[5] = cfg.addr[4]; + bt_bd_addr[6] = cfg.addr[3]; + bt_bd_addr[7] = cfg.addr[2]; + bt_bd_addr[8] = cfg.addr[1]; + bt_bd_addr[9] = cfg.addr[0]; + memcpy(&bt_voice[4], cfg.voice, 2); + memcpy(&bt_codec[4], cfg.codec, 4); + memcpy(&bt_radio[4], cfg.radio, 6); + memcpy(&bt_tx_pwr_offset[4], cfg.tx_pwr_offset, 3); + memcpy(&bt_sleep[4], cfg.sleep, 7); + memcpy(&bt_feature[4], cfg.feature, 2); + +init_start: + + ret = hci_stp_dev_init(hu); + /* error handling: turn of BT */ + if (unlikely(ret)) { + BT_WARN_FUNC("hci_stp_dev_init fail(%d)!\n", ret); + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) { + BT_WARN_FUNC("WMT turn off BT fail!\n"); + } + else { + BT_INFO_FUNC("WMT turn off BT ok!\n"); + } + return -ENODEV; + } + + BT_INFO_FUNC("hci_stp_dev_init ok\n"); + + set_bit(HCI_RUNNING, &hdev->flags); + + /*registered tx/rx path*/ + mtk_wcn_stp_register_if_rx(stp_rx_event_cb_directly); + + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); + mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, stp_tx_event_cb); + + /*use bluez*/ + mtk_wcn_stp_set_bluez(1); + + return 0; + } + else { + BT_WARN_FUNC("STP is not ready!\n"); + return -ENODEV; + } +} + +/* Reset device */ +static int hci_stp_flush(struct hci_dev *hdev) +{ + struct hci_stp *hu; + + BT_DBG_FUNC("start\n"); + if (!hdev || !hdev->driver_data) { + BT_WARN_FUNC("invalid hdev(0x%p) or drv data(0x%p)\n", + hdev, (hdev) ? hdev->driver_data : hdev); + return -EFAULT; + } + + hu = (struct hci_stp *)hdev->driver_data; + + /* clear txq and free all skb in it */ + hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ); + skb_queue_purge(&hu->txq); + hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ); + + BT_INFO_FUNC("done\n"); + return 0; +} + +/* Close device */ +static int hci_stp_close(struct hci_dev *hdev) +{ +#if HCI_STP_SAFE_RESET + struct hci_stp *hu; + long ret; +#endif + + BT_INFO_FUNC("hdev(0x%p)\n", hdev); + + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) { + return 0; + } + + hci_stp_flush(hdev); + hdev->flush = NULL; + +#if HCI_STP_SAFE_RESET + hu = (struct hci_stp *)hdev->driver_data; + if (hu) { + /* double waiting time in case of busy system */ + ret = wait_event_timeout((hu->reset_wq), + (atomic_read(&hu->reset_count) == 0), + msecs_to_jiffies(BT_CMD_DELAY_MS_RESET*2)); + if ( (!ret) || (atomic_read(&hu->reset_count) != 0) ) { + BT_WARN_FUNC("wait on-going reset finish fail,f(%d),c(%d),ret(%u)\n", + BT_GET_HDEV_RST_FG(hdev), + atomic_read(&hu->reset_count), + jiffies_to_msecs(ret)); + } + else { + BT_DBG_FUNC("check reset log,f(%d),c(%d),ret(%u)\n", + BT_GET_HDEV_RST_FG(hdev), + atomic_read(&hu->reset_count), + jiffies_to_msecs(ret)); + } + } +#endif + + /* clear txq and free all skb in it */ + hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ); + skb_queue_purge(&hu->txq); + hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ); + + /*unregistered tx/rx path*/ + mtk_wcn_stp_register_if_rx(NULL); + + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); + mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, NULL); + + /*not use bluez*/ + mtk_wcn_stp_set_bluez(0); + + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) { + BT_WARN_FUNC("WMT turn off BT fail!\n"); + } + else { + BT_INFO_FUNC("WMT turn off BT OK!\n"); + } + + return 0; +} + +/* Send frames from HCI layer */ +static int hci_stp_send_frame(struct sk_buff *skb) +{ + struct hci_dev* hdev = (struct hci_dev *) skb->dev; + struct hci_stp *hu; + + BT_TRC_FUNC(); + if (!hdev) { + BT_ERR_FUNC("Null hdev in skb\n"); + return -ENODEV; + } + + if (!test_bit(HCI_RUNNING, &hdev->flags)) { + BT_ERR_FUNC("no HCI_RUNNING in hdev->flags(0x%lx)\n", hdev->flags); + return -EBUSY; + } + + hu = (struct hci_stp *) hdev->driver_data; + + BT_LOUD_FUNC("%s:type(%d)len(%d)\n", + hdev->name, bt_cb(skb)->pkt_type, skb->len); + +#if 0 /* just timestamp?? */ + if (gHciStpDbgLevel >= BT_LOG_DBG) + { + struct timeval now; + do_gettimeofday(&now); + printk("%s: sec = %ld, --> usec --> %ld\n", + __FUNCTION__, now.tv_sec, now.tv_usec); + } +#endif + + /* Prepend skb with frame type. Is it safe to do skb_push? */ + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); + + /* George: is no lock ok?? Add hci_stp_txq_lock and unlock! */ + hci_stp_txq_lock(HCI_STP_TXQ_IN_BLZ); + /*Queue a buffer at the end of a list. This function takes no locks + * and you must therefore hold required locks before calling it. + */ + skb_queue_tail(&hu->txq, skb); + hci_stp_txq_unlock(HCI_STP_TXQ_IN_BLZ); + + /* George: adapt different tx_kick function */ + hci_stp_tx_kick(); + + return 0; +} + +static void hci_stp_destruct(struct hci_dev *hdev) +{ + BT_INFO_FUNC("start hdev(0x%p)\n", hdev); + if (!hdev) { + return; + } + + BT_DBG_FUNC("%s\n", hdev->name); + hci_stp_tx_deinit((struct hci_stp *)hdev->driver_data); + kfree(hdev->driver_data); + + BT_DBG_FUNC("done\n"); +} + +static int __init hci_stp_init(void) +{ + struct hci_stp *hu = NULL; + + BT_DBG_FUNC("HCI STP driver ver %s\n", VERSION); + + if (!(hu = kzalloc(sizeof(struct hci_stp), /*GFP_KERNEL*/GFP_ATOMIC))) { + BT_ERR_FUNC("Can't allocate control structure\n"); + return -ENOMEM; + } + + BT_DBG_FUNC("hu 0x%08x\n", (int)hu); + + /* + used to stored pending skb + */ + skb_queue_head_init(&hu->txq); + + /* + Initialize and register HCI device + */ + hdev = hci_alloc_dev(); + if (!hdev) { + if (hu){ + kfree(hu); + hu = NULL; + } + + BT_ERR_FUNC("Can't allocate HCI device\n"); + return -ENOMEM; + } + + hu->hdev = hdev; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) + hdev->type = HCI_UART; +#else + hdev->bus = HCI_UART; + hdev->dev_type = HCI_BREDR; +#endif + hdev->driver_data = hu; + + BT_DBG_FUNC("hdev->driver_data 0x%08x\n", (int)hdev->driver_data); + hdev->open = hci_stp_open; + hdev->close = hci_stp_close; + hdev->flush = hci_stp_flush; + hdev->send = hci_stp_send_frame; + hdev->destruct = hci_stp_destruct; + + hdev->owner = THIS_MODULE; + + BT_DBG_FUNC("HCI_QUIRK_NO_RESET\n"); + + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); + + if (hci_register_dev(hdev) < 0) { + BT_ERR_FUNC("Can't register HCI device\n"); + kfree(hu); + hu = NULL; + hci_free_dev(hdev); + hdev = NULL; + return -ENODEV; + } + +#if HCI_STP_SAFE_RESET + atomic_set(&hu->reset_count, 0); + init_waitqueue_head(&hu->reset_wq); +#endif + + /* George: adapt different tx_init function */ + hci_stp_tx_init(hu); + +#if (HCI_STP_DEV_INIT == HCI_STP_DEV_INIT_THRD) + /* init_work in heap */ + INIT_WORK(&hu->init_work, hci_stp_dev_init_work); + spin_lock_init(&hu->init_lock); +#endif + + mtk_wcn_stp_register_if_rx(NULL); + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); + mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, NULL); + + BT_INFO_FUNC("HCI-STP Drv(%s),dev(0x%p),data(0x%p) init done\n", VERSION, hdev, hdev->driver_data); + return 0; +} + +static void __exit hci_stp_exit(void) +{ + struct hci_stp *hu = (struct hci_stp *)hdev->driver_data; + BT_TRC_FUNC(); + + mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL); + mtk_wcn_stp_register_tx_event_cb(BT_TASK_INDX, NULL); + + hci_unregister_dev(hdev); + + /* George: adapt different tx_deinit function */ + //tasklet_kill(&hci_tx_tasklet); + + skb_queue_purge(&hu->txq); + + /* hci_stp_destruct does this */ + /*kfree(hdev->driver_data);*/ + hci_free_dev(hdev); + + hdev = NULL; + BT_INFO_FUNC("done\n"); +} + +module_init(hci_stp_init); +module_exit(hci_stp_exit); + +module_param(reset, bool, 0644); +MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); + +MODULE_AUTHOR("Mediatek Inc."); +MODULE_DESCRIPTION("Bluetooth HCI STP driver ver " VERSION); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL"); + + diff --git a/drivers/mtk_wcn_combo/drv_fm/Makefile b/drivers/mtk_wcn_combo/drv_fm/Makefile new file mode 100755 index 000000000000..8ba480620967 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/Makefile @@ -0,0 +1,47 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# Makefile generated by Mediatek +# fm support +MTK_FM_SUPPORT = yes +CUSTOM_KERNEL_FM = mt6620 +ifeq ($(MTK_FM_SUPPORT), yes) +ifeq ($(CUSTOM_KERNEL_FM), mt6620) + +obj-$(CONFIG_MTK_COMBO_FM) += private/ +obj-$(CONFIG_MTK_COMBO_FM) += public/ + +endif +endif \ No newline at end of file diff --git a/drivers/mtk_wcn_combo/drv_fm/include/fm.h b/drivers/mtk_wcn_combo/drv_fm/include/fm.h new file mode 100755 index 000000000000..fbabe94e88f5 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/include/fm.h @@ -0,0 +1,520 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* alps/ALPS_SW/TRUNK/MAIN/alps/kernel/arch/arm/mach-mt6516/include/mach/fm.h + * + * (C) Copyright 2009 + * MediaTek + * William Chung + * + * MT6516 AR10x0 FM Radio Driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __FM_H__ +#define __FM_H__ + +//#define FMDEBUG + +#include +#include + +//scan sort ways +enum{ + FM_SCAN_SORT_NON = 0, + FM_SCAN_SORT_UP, + FM_SCAN_SORT_DOWN, + FM_SCAN_SORT_MAX +}; + +//***************************************************************************************** +//***********************************FM config for customer *********************************** +//***************************************************************************************** +//RX +#define FMR_RSSI_TH_LONG 0x0301 //FM radio long antenna RSSI threshold(11.375dBuV) +#define FMR_RSSI_TH_SHORT 0x02E0 //FM radio short antenna RSSI threshold(-1dBuV) +#define FMR_CQI_TH 0x00E9 //FM radio Channel quality indicator threshold(0x0000~0x00FF) +#define FMR_SEEK_SPACE 1 //FM radio seek space,1:100KHZ; 2:200KHZ +#define FMR_SCAN_CH_SIZE 40 //FM radio scan max channel size +#define FMR_BAND 1 //FM radio band, 1:87.5MHz~108.0MHz; 2:76.0MHz~90.0MHz; 3:76.0MHz~108.0MHz; 4:special +#define FMR_BAND_FREQ_L 875 //FM radio special band low freq(Default 87.5MHz) +#define FMR_BAND_FREQ_H 1080 //FM radio special band high freq(Default 108.0MHz) +#define FM_SCAN_SORT_SELECT FM_SCAN_SORT_DOWN + +//TX +#define FMTX_PWR_LEVEL_MAX 120 //FM transmitter power level, rang: 85db~120db, default 120db + +//***************************************************************************************** +//***********************************FM config for engineer *********************************** +//***************************************************************************************** +//RX +#define FMR_MR_TH 0x01BD //FM radio MR threshold +#define ADDR_SCAN_TH 0xE0 //scan thrshold register +#define ADDR_CQI_TH 0xE1 //scan CQI register + +//TX +#define FMTX_SCAN_HOLE_LOW 923 //92.3MHz~95.4MHz should not show to user +#define FMTX_SCAN_HOLE_HIGH 954 //92.3MHz~95.4MHz should not show to user +//***************************************************************************************** + +#define FM_NAME "fm" +#define FM_DEVICE_NAME "/dev/fm" + +// errno +#define FM_SUCCESS 0 +#define FM_FAILED 1 +#define FM_EPARM 2 +#define FM_BADSTATUS 3 +#define FM_TUNE_FAILED 4 +#define FM_SEEK_FAILED 5 +#define FM_BUSY 6 +#define FM_SCAN_FAILED 7 + +// band + +#define FM_BAND_UNKNOWN 0 +#define FM_BAND_UE 1 // US/Europe band 87.5MHz ~ 108MHz (DEFAULT) +#define FM_BAND_JAPAN 2 // Japan band 76MHz ~ 90MHz +#define FM_BAND_JAPANW 3 // Japan wideband 76MHZ ~ 108MHz +#define FM_BAND_SPECIAL 4 // special band between 76MHZ and 108MHz +#define FM_BAND_DEFAULT FM_BAND_UE +#define FM_FREQ_MIN FMR_BAND_FREQ_L +#define FM_FREQ_MAX FMR_BAND_FREQ_H +#define FM_RAIDO_BAND FM_BAND_UE +// space +#define FM_SPACE_UNKNOWN 0 +#define FM_SPACE_100K 1 +#define FM_SPACE_200K 2 +#define FM_SPACE_DEFAULT FMR_SEEK_SPACE +#define FM_SEEK_SPACE FMR_SEEK_SPACE + +//max scan chl num +#define FM_MAX_CHL_SIZE FMR_SCAN_CH_SIZE +// auto HiLo +#define FM_AUTO_HILO_OFF 0 +#define FM_AUTO_HILO_ON 1 + +// seek direction +#define FM_SEEK_UP 0 +#define FM_SEEK_DOWN 1 + +#define FM_CHIP_AR1000 0x1000 +#define FM_CHIP_MT5192 0x91 +#define FM_CHIP_MT5193 0x92 +#define FM_CHIP_MT6616 0x6616 +#define FM_CHIP_MT6620 0x6620 +#define FM_CHIP_MT6626 0x6626 +#define FM_CHIP_MT6628 0x6628 +#define FM_CHIP_UNSUPPORTED 0xffff + +// seek threshold +#define FM_SEEKTH_LEVEL_DEFAULT 4 + +#define FM_IOC_MAGIC 0xf5 // FIXME: any conflict? + +struct fm_tune_parm { + uint8_t err; + uint8_t band; + uint8_t space; + uint8_t hilo; + uint16_t freq; // IN/OUT parameter +}; + +struct fm_seek_parm { + uint8_t err; + uint8_t band; + uint8_t space; + uint8_t hilo; + uint8_t seekdir; + uint8_t seekth; + uint16_t freq; // IN/OUT parameter +}; + +struct fm_scan_parm { + uint8_t err; + uint8_t band; + uint8_t space; + uint8_t hilo; + uint16_t freq; // OUT parameter + uint16_t ScanTBL[16]; //need no less than the chip + uint16_t ScanTBLSize; //IN/OUT parameter +}; + +struct fm_ch_rssi{ + uint16_t freq; + int rssi; +}; + +struct fm_rssi_req{ + uint16_t num; + uint16_t read_cnt; + struct fm_ch_rssi cr[16*16]; +}; + +struct fm_hw_info{ + int chip_id; //chip ID, eg. 6620 + int eco_ver; //chip ECO version, eg. E3 + int rom_ver; //FM DSP rom code version, eg. V2 + int patch_ver; //FM DSP patch version, eg. 1.11 + int reserve; +}; + +//For RDS feature +typedef struct +{ + uint8_t TP; + uint8_t TA; + uint8_t Music; + uint8_t Stereo; + uint8_t Artificial_Head; + uint8_t Compressed; + uint8_t Dynamic_PTY; + uint8_t Text_AB; + uint32_t flag_status; +}RDSFlag_Struct; + +typedef struct +{ + uint16_t Month; + uint16_t Day; + uint16_t Year; + uint16_t Hour; + uint16_t Minute; + uint8_t Local_Time_offset_signbit; + uint8_t Local_Time_offset_half_hour; +}CT_Struct; + +typedef struct +{ + int16_t AF_Num; + int16_t AF[2][25]; //100KHz + uint8_t Addr_Cnt; + uint8_t isMethod_A; + uint8_t isAFNum_Get; +}AF_Info; + +typedef struct +{ + uint8_t PS[3][8]; + uint8_t Addr_Cnt; +}PS_Info; + +typedef struct +{ + uint8_t TextData[4][64]; + uint8_t GetLength; + uint8_t isRTDisplay; + uint8_t TextLength; + uint8_t isTypeA; + uint8_t BufCnt; + uint16_t Addr_Cnt; +}RT_Info; + +struct rds_raw_data +{ + int dirty; //indicate if the data changed or not + int len; //the data len form chip + uint8_t data[146]; +}; + +struct rds_group_cnt +{ + unsigned long total; + unsigned long groupA[16]; //RDS groupA counter + unsigned long groupB[16]; //RDS groupB counter +}; + +enum rds_group_cnt_opcode +{ + RDS_GROUP_CNT_READ = 0, + RDS_GROUP_CNT_WRITE, + RDS_GROUP_CNT_RESET, + RDS_GROUP_CNT_MAX +}; + +struct rds_group_cnt_req +{ + int err; + enum rds_group_cnt_opcode op; + struct rds_group_cnt gc; +}; + +typedef struct +{ + CT_Struct CT; + RDSFlag_Struct RDSFlag; + uint16_t PI; + uint8_t Switch_TP; + uint8_t PTY; + AF_Info AF_Data; + AF_Info AFON_Data; + uint8_t Radio_Page_Code; + uint16_t Program_Item_Number_Code; + uint8_t Extend_Country_Code; + uint16_t Language_Code; + PS_Info PS_Data; + uint8_t PS_ON[8]; + RT_Info RT_Data; + //uint16_t Block_Backup[32][4]; + //uint16_t Group_Cnt[32]; + //uint8_t EINT_Flag; + //uint8_t RDS_Flag; + uint16_t event_status; //will use RDSFlag_Struct RDSFlag->flag_status to check which event, is that ok? +} RDSData_Struct; + + +//Need care the following definition. +//valid Rds Flag for notify +typedef enum { + RDS_FLAG_IS_TP = 0x0001, // Program is a traffic program + RDS_FLAG_IS_TA = 0x0002, // Program currently broadcasts a traffic ann. + RDS_FLAG_IS_MUSIC = 0x0004, // Program currently broadcasts music + RDS_FLAG_IS_STEREO = 0x0008, // Program is transmitted in stereo + RDS_FLAG_IS_ARTIFICIAL_HEAD = 0x0010, // Program is an artificial head recording + RDS_FLAG_IS_COMPRESSED = 0x0020, // Program content is compressed + RDS_FLAG_IS_DYNAMIC_PTY = 0x0040, // Program type can change + RDS_FLAG_TEXT_AB = 0x0080 // If this flag changes state, a new radio text string begins +} RdsFlag; + +typedef enum { + RDS_EVENT_FLAGS = 0x0001, // One of the RDS flags has changed state + RDS_EVENT_PI_CODE = 0x0002, // The program identification code has changed + RDS_EVENT_PTY_CODE = 0x0004, // The program type code has changed + RDS_EVENT_PROGRAMNAME = 0x0008, // The program name has changed + RDS_EVENT_UTCDATETIME = 0x0010, // A new UTC date/time is available + RDS_EVENT_LOCDATETIME = 0x0020, // A new local date/time is available + RDS_EVENT_LAST_RADIOTEXT = 0x0040, // A radio text string was completed + RDS_EVENT_AF = 0x0080, // Current Channel RF signal strength too weak, need do AF switch + RDS_EVENT_AF_LIST = 0x0100, // An alternative frequency list is ready + RDS_EVENT_AFON_LIST = 0x0200, // An alternative frequency list is ready + RDS_EVENT_TAON = 0x0400, // Other Network traffic announcement start + RDS_EVENT_TAON_OFF = 0x0800, // Other Network traffic announcement finished. + RDS_EVENT_RDS = 0x2000, // RDS Interrupt had arrived durint timer period + RDS_EVENT_NO_RDS = 0x4000, // RDS Interrupt not arrived durint timer period + RDS_EVENT_RDS_TIMER = 0x8000 // Timer for RDS Bler Check. ---- BLER block error rate +} RdsEvent; + +struct fm_rds_tx_parm { + uint8_t err; + uint16_t pi; + uint16_t ps[12]; // 4 ps + uint16_t other_rds[87]; // 0~29 other groups + uint8_t other_rds_cnt; // # of other group +}; + +typedef struct fm_rds_tx_req{ + unsigned char pty; // 0~31 integer + unsigned char rds_rbds; // 0:RDS, 1:RBDS + unsigned char dyn_pty; // 0:static, 1:dynamic + unsigned short pi_code; // 2-byte hex + unsigned char ps_buf[8]; // hex buf of PS + unsigned char ps_len; // length of PS, must be 0 / 8" + unsigned char af; // 0~204, 0:not used, 1~204:(87.5+0.1*af)MHz + unsigned char ah; // Artificial head, 0:no, 1:yes + unsigned char stereo; // 0:mono, 1:stereo + unsigned char compress; // Audio compress, 0:no, 1:yes + unsigned char tp; // traffic program, 0:no, 1:yes + unsigned char ta; // traffic announcement, 0:no, 1:yes + unsigned char speech; // 0:music, 1:speech +}fm_rds_tx_req; + +#define TX_SCAN_MAX 10 +#define TX_SCAN_MIN 1 +struct fm_tx_scan_parm { + uint8_t err; + uint8_t band; //87.6~108MHz + uint8_t space; + uint8_t hilo; + uint16_t freq; // start freq, if less than band min freq, then will use band min freq + uint8_t scandir; + uint16_t ScanTBL[TX_SCAN_MAX]; //need no less than the chip + uint16_t ScanTBLSize; //IN: desired size, OUT: scan result size +}; + +struct fm_gps_rtc_info{ + int err; //error number, 0: success, other: err code + int retryCnt; //GPS mnl can decide retry times + int ageThd; //GPS 3D fix time diff threshold + int driftThd; //GPS RTC drift threshold + struct timeval tvThd; //time value diff threshold + int age; //GPS 3D fix time diff + int drift; //GPS RTC drift + union{ + unsigned long stamp; //time stamp in jiffies + struct timeval tv; //time stamp value in RTC + }; + int flag; //rw flag +}; + +typedef enum +{ + FM_I2S_ON = 0, + FM_I2S_OFF +}fm_i2s_state; + +typedef enum +{ + FM_I2S_MASTER = 0, + FM_I2S_SLAVE +}fm_i2s_mode; + +typedef enum +{ + FM_I2S_32K = 0, + FM_I2S_44K, + FM_I2S_48K +}fm_i2s_sample; + +struct fm_i2s_setting{ + int onoff; + int mode; + int sample; +}; + +typedef enum{ + FM_RX = 0, + FM_TX = 1 +}FM_PWR_T; + +#define FM_IOCTL_POWERUP _IOWR(FM_IOC_MAGIC, 0, struct fm_tune_parm*) +#define FM_IOCTL_POWERDOWN _IOWR(FM_IOC_MAGIC, 1, int32_t*) +#define FM_IOCTL_TUNE _IOWR(FM_IOC_MAGIC, 2, struct fm_tune_parm*) +#define FM_IOCTL_SEEK _IOWR(FM_IOC_MAGIC, 3, struct fm_seek_parm*) +#define FM_IOCTL_SETVOL _IOWR(FM_IOC_MAGIC, 4, uint32_t*) +#define FM_IOCTL_GETVOL _IOWR(FM_IOC_MAGIC, 5, uint32_t*) +#define FM_IOCTL_MUTE _IOWR(FM_IOC_MAGIC, 6, uint32_t*) +#define FM_IOCTL_GETRSSI _IOWR(FM_IOC_MAGIC, 7, uint32_t*) +#define FM_IOCTL_SCAN _IOWR(FM_IOC_MAGIC, 8, struct fm_scan_parm*) +#define FM_IOCTL_STOP_SCAN _IO(FM_IOC_MAGIC, 9) +#define FM_IOCTL_POWERUP_TX _IOWR(FM_IOC_MAGIC, 20, struct fm_tune_parm*) +#define FM_IOCTL_TUNE_TX _IOWR(FM_IOC_MAGIC, 21, struct fm_tune_parm*) +#define FM_IOCTL_RDS_TX _IOWR(FM_IOC_MAGIC, 22, struct fm_rds_tx_parm*) + +//IOCTL and struct for test +#define FM_IOCTL_GETCHIPID _IOWR(FM_IOC_MAGIC, 10, uint16_t*) +#define FM_IOCTL_EM_TEST _IOWR(FM_IOC_MAGIC, 11, struct fm_em_parm*) +#define FM_IOCTL_RW_REG _IOWR(FM_IOC_MAGIC, 12, struct fm_ctl_parm*) +#define FM_IOCTL_GETMONOSTERO _IOWR(FM_IOC_MAGIC, 13, uint16_t*) +#define FM_IOCTL_GETCURPAMD _IOWR(FM_IOC_MAGIC, 14, uint16_t*) +#define FM_IOCTL_GETGOODBCNT _IOWR(FM_IOC_MAGIC, 15, uint16_t*) +#define FM_IOCTL_GETBADBNT _IOWR(FM_IOC_MAGIC, 16, uint16_t*) +#define FM_IOCTL_GETBLERRATIO _IOWR(FM_IOC_MAGIC, 17, uint16_t*) + + +//IOCTL for RDS +#define FM_IOCTL_RDS_ONOFF _IOWR(FM_IOC_MAGIC, 18, uint16_t*) +#define FM_IOCTL_RDS_SUPPORT _IOWR(FM_IOC_MAGIC, 19, int32_t*) + +#define FM_IOCTL_RDS_SIM_DATA _IOWR(FM_IOC_MAGIC, 23, uint32_t*) +#define FM_IOCTL_IS_FM_POWERED_UP _IOWR(FM_IOC_MAGIC, 24, uint32_t*) + +//IOCTL for FM Tx +#define FM_IOCTL_TX_SUPPORT _IOWR(FM_IOC_MAGIC, 25, int32_t*) +#define FM_IOCTL_RDSTX_SUPPORT _IOWR(FM_IOC_MAGIC, 26, int32_t*) +#define FM_IOCTL_RDSTX_ENABLE _IOWR(FM_IOC_MAGIC, 27, int32_t*) +#define FM_IOCTL_TX_SCAN _IOWR(FM_IOC_MAGIC, 28, struct fm_tx_scan_parm*) + +//IOCTL for FM over BT +#define FM_IOCTL_OVER_BT_ENABLE _IOWR(FM_IOC_MAGIC, 29, int32_t*) + +//IOCTL for FM ANTENNA SWITCH +#define FM_IOCTL_ANA_SWITCH _IOWR(FM_IOC_MAGIC, 30, int32_t*) +#define FM_IOCTL_GETCAPARRAY _IOWR(FM_IOC_MAGIC, 31, int32_t*) + +//IOCTL for FM compensation by GPS RTC +#define FM_IOCTL_GPS_RTC_DRIFT _IOWR(FM_IOC_MAGIC, 32, struct fm_gps_rtc_info*) + +//IOCTL for FM I2S Setting +#define FM_IOCTL_I2S_SETTING _IOWR(FM_IOC_MAGIC, 33, struct fm_i2s_setting*) + +#define FM_IOCTL_RDS_GROUPCNT _IOWR(FM_IOC_MAGIC, 34, struct rds_group_cnt_req*) +#define FM_IOCTL_RDS_GET_LOG _IOWR(FM_IOC_MAGIC, 35, struct rds_raw_data*) + +#define FM_IOCTL_SCAN_GETRSSI _IOWR(FM_IOC_MAGIC, 36, struct fm_rssi_req*) +#define FM_IOCTL_SETMONOSTERO _IOWR(FM_IOC_MAGIC, 37, int32_t) +#define FM_IOCTL_GET_HW_INFO _IOWR(FM_IOC_MAGIC, 38, struct fm_hw_info*) + +#define FM_IOCTL_DUMP_REG _IO(FM_IOC_MAGIC, 0xFF) + +enum group_idx { + mono=0, + stereo, + RSSI_threshold, + HCC_Enable, + PAMD_threshold, + Softmute_Enable, + De_emphasis, + HL_Side, + Demod_BW, + Dynamic_Limiter, + Softmute_Rate, + AFC_Enable, + Softmute_Level, + Analog_Volume, + GROUP_TOTAL_NUMS +}; + +enum item_idx { + Sblend_OFF=0, + Sblend_ON, + ITEM_TOTAL_NUMS +}; + +struct fm_ctl_parm { + uint8_t err; + uint8_t addr; + uint16_t val; + uint16_t rw_flag;//0:write, 1:read +}; + +struct fm_em_parm { + uint16_t group_idx; + uint16_t item_idx; + uint32_t item_value; +}; +#endif // __FM_H__ diff --git a/drivers/mtk_wcn_combo/drv_fm/private/Makefile b/drivers/mtk_wcn_combo/drv_fm/private/Makefile new file mode 100755 index 000000000000..0b5ee405053f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/private/Makefile @@ -0,0 +1,51 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# Makefile generated by Mediatek +# fm support +MTK_FM_SUPPORT=yes +CUSTOM_KERNEL_FM=mt6620 +ifeq ($(MTK_FM_SUPPORT), yes) +ifeq ($(CUSTOM_KERNEL_FM), mt6620) +ccflags-y := -I$(src)/../include -I$(src)/../../common/include -I$(src)/../../common/linux/include -I$(src)/../public/ +KERNEL_PATH := $(src) +OBJ_PATH := $(src) + +obj-$(CONFIG_MTK_COMBO_FM) += mtk_fm_priv.o +mtk_fm_priv-objs := mtk_fm.o +always := $(shell cp -f $(KERNEL_PATH)/mtk_fm.o.new $(OBJ_PATH)/mtk_fm.o) + +endif +endif diff --git a/drivers/mtk_wcn_combo/drv_fm/private/mtk_fm.h b/drivers/mtk_wcn_combo/drv_fm/private/mtk_fm.h new file mode 100755 index 000000000000..4e20119c5b27 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/private/mtk_fm.h @@ -0,0 +1,116 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#ifndef __MTK_FM_H__ +#define __MTK_FM_H__ + +#include + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +//#define HiSideTableSize 1 +#define FM_TX_PWR_CTRL_FREQ_THR 890 +#define FM_TX_PWR_CTRL_TMP_THR_UP 45 +#define FM_TX_PWR_CTRL_TMP_THR_DOWN 0 + +#define FM_TX_TRACKING_TIME_MAX 10000 //TX VCO tracking time, default 100ms + +enum fm_priv_state{ + UNINITED, + INITED +}; + +enum fm_adpll_state{ + FM_ADPLL_ON, + FM_ADPLL_OFF +}; + +enum fm_adpll_clk{ + FM_ADPLL_16M, + FM_ADPLL_15M +}; + +enum fm_mcu_desense{ + FM_MCU_DESENSE_ENABLE, + FM_MCU_DESENSE_DISABLE +}; + +struct fm_priv_cb { + //Basic functions. + int (*hl_side)(uint16_t freq, int *hl); + int (*adpll_freq_avoid)(uint16_t freq, int *freqavoid); + int (*mcu_freq_avoid)(uint16_t freq, int *freqavoid); + int (*tx_pwr_ctrl)(uint16_t freq, int *ctr); + int (*rtc_drift_ctrl)(uint16_t freq, int *ctr); + int (*tx_desense_wifi)(uint16_t freq, int *ctr); +}; + +struct fm_priv{ + int state; + void *data; + struct fm_priv_cb priv_tbl; +}; + +struct fm_op_cb { + //Basic functions. + int (*read)(uint8_t addr, uint16_t *val); + int (*write)(uint8_t addr, uint16_t val); + int (*setbits)(uint8_t addr, uint16_t bits, uint16_t mask); + int (*rampdown)(void); +}; + +struct fm_op{ + int state; + void *data; + struct fm_op_cb op_tbl; +}; + +#define FMR_ASSERT(a) { \ + if ((a) == NULL) { \ + printk("%s,invalid pointer\n", __func__);\ + return -ERR_INVALID_BUF; \ + } \ + } + +int fm_priv_register(struct fm_priv *pri, struct fm_op *op); +int fm_priv_unregister(struct fm_priv *pri, struct fm_op *op); + +#endif //__MTK_FM_H__ diff --git a/drivers/mtk_wcn_combo/drv_fm/public/Makefile b/drivers/mtk_wcn_combo/drv_fm/public/Makefile new file mode 100755 index 000000000000..9860d86feea7 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/public/Makefile @@ -0,0 +1,47 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# Makefile generated by Mediatek +# fm support +MTK_FM_SUPPORT=yes +CUSTOM_KERNEL_FM=mt6620 +ifeq ($(MTK_FM_SUPPORT), yes) +ifeq ($(CUSTOM_KERNEL_FM), mt6620) +ccflags-y := -I$(src)/../include -I$(src)/../../common/include -I$(src)/../../common/linux/include + +obj-$(CONFIG_MTK_COMBO_FM) += mt6620_fm_drv.o +mt6620_fm_drv-objs := mt6620_fm.o mt6620_fm_lib.o mt6620_rds.o +endif +endif \ No newline at end of file diff --git a/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.c b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.c new file mode 100755 index 000000000000..981b68fe001b --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.c @@ -0,0 +1,5257 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#include + +#ifdef FM_TASK_INFO_DEBUG +#include +#endif + +#include +#include + +#include +#include +#include +#include // udelay() +#include // device_create() +#include +#include +#include +#include +#include + +#include // get_user() + +#include "fm.h" +//#include +#ifdef MT6573 +#include +#endif +//#include + +#include "stp_exp.h" +#include "wmt_exp.h" + +#include "mt6620_fm.h" +#include "mt6620_fm_lib.h" +#include "../private/mtk_fm.h" +#include "mt6620_fm_reg.h" + +#ifdef CTP_CHECK_FM +extern void tpd_get_fm_frequency(int16_t freq); +#endif + +#define FM_VOL_MAX 0x2B // 43 volume(0-15) + +#define FM_DEV_MAJOR 193 +static int FM_major = FM_DEV_MAJOR; /* dynamic allocation */ + +#define FM_PROC_FILE "fm" +static struct proc_dir_entry *g_fm_proc = NULL; + +#define FM_PROC_CONFIG "fmconfig" +static struct fm_config g_fm_config; + +uint32_t g_dbg_level = 0xfffffff5; // Debug level of FM + +static struct fm *fm_cb = NULL; //fm main data structure +struct fm_priv priv; //fm priv data, and will be linked to fm main data structure + +volatile int16_t _current_frequency = 0xFFFF; +static unsigned char *tx_buf = NULL; + +volatile uint16_t seek_result = 0; +uint16_t scan_result[MT6620_SCANTBL_SIZE] = {0}; +struct rds_rx rds_rx_result; +volatile uint16_t rds_rx_size = 0; +static volatile uint32_t flag = 0; +static spinlock_t flag_lock; + +static volatile uint16_t fspi_rd = 0; + +static struct fm_gps_rtc_info gps_rtc_info; + +extern uint32_t gBLER_CHK_INTERVAL; +extern uint16_t GOOD_BLK_CNT; +extern uint16_t BAD_BLK_CNT; +extern uint8_t BAD_BLK_RATIO; + +static struct timer_list fm_timer; +static struct fm_timer_sys timer_sys; + +static volatile int chip_rst_state = FM_WHOLECHIP_RST_OFF; +static volatile int subsys_rst_state = FM_SUBSYS_RST_OFF; +static struct fm_context *fm_cxt; + +#ifndef DECLARE_MUTEX +#define DECLARE_MUTEX(name) DEFINE_SEMAPHORE(name) +#endif +static DECLARE_WAIT_QUEUE_HEAD(fm_wq); +static DECLARE_MUTEX(fm_ops_mutex); //protect FM ops: open, close, read, ioctl +static DECLARE_MUTEX(fm_read_mutex); //protect RDS good/bad block global val +static DECLARE_MUTEX(fm_rds_mutex); //protec RDS ps/rt ... +static DECLARE_MUTEX(fm_timer_mutex); //protec FM timer +static DECLARE_MUTEX(fm_cmd_mutex); //protect FM HW access +static DECLARE_MUTEX(fm_rtc_mutex); //protect FM GPS RTC drift info +static DECLARE_MUTEX(fm_rxtx_mutex); //protect FM RX TX mode switch + +/****************************************************************************** + * FUNCTION PROTOTYPES + *****************************************************************************/ +//schedule func +void stp_rx_event_cb(void); //called by stp driver +static void fm_timer_func(unsigned long data); //called by timer timeout + +//worker func +static void fm_rx_worker_func(struct work_struct *work); //scheduled by stp_rx_event_cb +static void fm_rds_reset_worker_func(struct work_struct *work); //scheduled by fm_timer_func +static void fm_tx_rtc_ctrl_worker_func(struct work_struct *work); // +static void fm_tx_power_ctrl_worker_func(struct work_struct *work); +static void fm_tx_desense_wifi_worker_func(struct work_struct *work); +static void fm_rst_recover_worker_func(struct work_struct *work); +static void fm_subsys_recover_worker_func(struct work_struct *work); + +//normal func +static int fm_enable_rds_BlerCheck(struct fm *fm); +static int fm_disable_rds_BlerCheck(void); + +static int fm_hw_reset(void); +static int fm_recover_func(struct fm *fm, struct fm_context *cxt); + +static int fm_tx_scan(struct fm *fm, struct fm_tx_scan_parm *parm); +int fm_send_wait_timeout(unsigned char* tx_buf, + uint16_t pkt_size, + int flag_mask, + int retry_cnt, + int timeout); + +static int MT6620_TxScan_SetFreq(uint16_t freq); +static int MT6620_TxScan_GetCQI(int16_t *pRSSI, int16_t *pPAMD, int16_t *pMR); +static int MT6620_TxScan_IsEmptyChannel(int16_t RSSI, int16_t PAMD, int16_t MR, int *empty); +static int MT6620_TxScan(uint16_t min_freq, uint16_t max_freq, uint16_t *pFreq, uint16_t *pScanTBL, uint16_t *ScanTBLsize, uint16_t scandir, uint16_t space); +extern int MT6620_RDS_BlerCheck(struct fm *fm); +extern int MT6620_RDS_Eint_Handler(struct fm *fm, struct rds_rx *rds_raw, int rds_size); +extern int MT6620_RDS_OnOff(struct fm *fm, bool bFlag); +extern int rds_group_counter_get(struct rds_group_cnt *dst, struct rds_group_cnt *src); +extern int rds_group_counter_reset(struct rds_group_cnt *gc); + +int Delayms(uint32_t data); +int Delayus(uint32_t data); +int MT6620_read(uint8_t addr, uint16_t *val); +int MT6620_write(uint8_t addr, uint16_t val); +int MT6620_set_bits(uint8_t addr, uint16_t bits, uint16_t mask); +static int MT6620_Mute(bool mute); +static int MT6620_RampDown(void); +static int MT6620_RampDown_Tx(void); +static int MT6620_SetFreq(uint16_t freq); // functionality tune +static int MT6620_Fast_SetFreq(uint16_t freq); +static int MT6620_SetFreq_Tx(uint16_t freq); // functionality tune +static int MT6620_Seek( + uint16_t min_freq, uint16_t max_freq, + uint16_t *pFreq, + uint16_t seekdir, + uint16_t space); +static int MT6620_Scan( + uint16_t min_freq, uint16_t max_freq, + uint16_t *pFreq, //get the valid freq after scan + uint16_t *pScanTBL, + uint16_t *ScanTBLsize, + uint16_t scandir, + uint16_t space); +static int MT6620_ScanForceStop(void); +static int MT6620_GetCurRSSI(int *pRSSI); +static int MT6620_SetVol(uint8_t vol); +static int MT6620_GetVol(uint8_t *pVol); +#ifdef FMDEBUG +static int MT6620_dump_reg(void); +#endif +static int MT6620_GetMonoStereo(uint16_t *pMonoStereo); +static int MT6620_SetMonoStereo(int MonoStereo); +static int MT6620_GetCapArray(int *caparray); +static int MT6620_GetCurPamd(uint16_t *pPamdLevl); +static int MT6620_em_test(uint16_t group_idx, uint16_t item_idx, uint32_t item_value); +static int MT6620_Rds_Tx_Enable(uint8_t enable); +static int MT6620_Rds_Tx(uint16_t pi, uint16_t *ps, uint16_t *other_rds, uint8_t other_rds_cnt); +static int MT6620_I2S_Setting(int onoff, int mode, int sample); +static int MT6620_FMOverBT(int enable); +static int MT6620_ANA_SWITCH(int antenna); + +static int fm_setup_cdev(struct fm *fm); +static long fm_ops_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +static loff_t fm_ops_lseek(struct file *filp, loff_t off, int whence); +static ssize_t fm_ops_read(struct file *filp, char *buf, size_t len, loff_t *off); +static int fm_ops_open(struct inode *inode, struct file *filp); +static int fm_ops_release(struct inode *inode, struct file *filp); + +static int fm_get_process_path(struct fm *fm); +static int fm_get_gps_rtc_info(struct fm_gps_rtc_info *dst, struct fm_gps_rtc_info *src); +static int fm_rtc_compensation_init(struct fm *fm, struct fm_gps_rtc_info *rtc); +static int fm_timer_init(struct fm *fm, struct fm_timer_sys *fmtimer, struct timer_list *timer); + +static int fm_init(void); +static int fm_destroy(struct fm *fm); +static int fm_powerup(struct fm *fm, struct fm_tune_parm *parm); +static int fm_antenna_switch(struct fm *fm, int antenna); +static int fm_powerup_tx(struct fm *fm, struct fm_tune_parm *parm); +static int fm_powerdown(struct fm *fm, int type); +static int fm_tune(struct fm *fm, struct fm_tune_parm *parm); +static int fm_tune_tx(struct fm *fm, struct fm_tune_parm *parm); +static int fm_seek(struct fm *fm, struct fm_seek_parm *parm); +static int fm_scan(struct fm *fm, struct fm_scan_parm *parm); +static int fm_get_rssi_after_scan(struct fm *fm, struct fm_rssi_req *req); +static int fm_get_hw_info(struct fm *pfm, struct fm_hw_info *req); +static int fm_setvol(struct fm *fm, uint32_t vol); +static int fm_getvol(struct fm *fm, uint32_t *vol); +static int fm_getrssi(struct fm *fm, int *rssi); +static int fm_rds_tx(struct fm *fm, struct fm_rds_tx_parm *parm); +static int fm_over_bt(struct fm *fm, int enable); +static int fm_proc_read(char *page, char **start, off_t off, + int count, int *eof, void *data); +static int fm_proc_write(struct file *file, const char *buffer, + unsigned long count, void *data); +static int fmconfig_proc_read(char *page, char **start, off_t off, + int count, int *eof, void *data); +static int fmconfig_proc_write(struct file *file, const char *buffer, + unsigned long count, void *data); + +static struct file_operations fm_ops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fm_ops_ioctl, + .llseek = fm_ops_lseek, + .read = fm_ops_read, + .open = fm_ops_open, + .release = fm_ops_release, +}; + +/****************************************************************************** + *****************************************************************************/ + +/* + * delay ms + */ +int Delayms(uint32_t data) +{ + msleep(data); + FM_LOG_DBG(D_CMD,"delay %dms\n", data); + return 0; +} + +/* + * delay us + */ +int Delayus(uint32_t data) +{ + udelay(data); + FM_LOG_DBG(D_CMD,"delay %dus\n", data); + return 0; +} + +/*********************************************************** +Function: fm_send_wait_timeout() + +Description: send cmd to FM firmware and wait event + +Para: tx_buf--->send buffer + pkt_size--->the length of cmd + flag_mask--->the event flag mask + retry_cnt--->the retry conter + timeout--->timeout per cmd + +Return: 0, if success; error code, if failed +***********************************************************/ +int fm_send_wait_timeout(unsigned char* tx_buf, + uint16_t pkt_size, + int flag_mask, + int retry_cnt, + int timeout) +{ + int ret_val = 0; + int ret_time = 0; + + if((NULL == tx_buf) || (pkt_size < 0) || (0 == flag_mask) + || (retry_cnt > SW_RETRY_CNT_MAX) || (timeout > SW_WAIT_TIMEOUT_MAX)){ + FM_LOG_ERR(D_ALL,"%s():invalid para\n", __func__); + ret_val = -ERR_INVALID_PARA; + goto out; + } + FM_LOG_DBG(D_MAIN,"0,flag_mask=0x%08x\n", flag_mask); +sw_retry: + //FM_LOG_DBG(D_MAIN,"0,flag_mask=0x%08x\n", flag_mask); + if(mtk_wcn_stp_send_data(tx_buf, pkt_size, FM_TASK_INDX) == 0){ + FM_LOG_ERR(D_MAIN,"%s():send data over stp failed\n", __func__); + ret_val = -ERR_STP; //stp error is the most serious error, wo can do nothing but info APP + goto out; + }else{ + //FM_LOG_DBG(D_MAIN,"1,flag_mask=0x%08x\n", flag_mask); + ret_time = wait_event_timeout(fm_wq, ((flag & flag_mask) == flag_mask), timeout*HZ); + FM_LOG_DBG(D_MAIN,"[flag=0x%08x]\n", flag); + if(!ret_time){ + if(0 < retry_cnt--){ + FM_LOG_WAR(D_MAIN,"%s():wait even timeout, [retry_cnt=%d]\n", __func__, retry_cnt); + goto sw_retry; + }else{ + FM_LOG_ERR(D_MAIN,"%s():fatal error, SW retry failed, reset HW\n", __func__); + ret_val = -ERR_FW_NORES; //return fatal error + goto out; + } + } + FM_LOG_DBG(D_MAIN,"2,flag_mask=0x%08x\n", flag_mask); + spin_lock(&flag_lock); + flag &= ~flag_mask; + spin_unlock(&flag_lock); + } +out: + return ret_val; +} + +/* + * MT6620_read + */ +int MT6620_read(uint8_t addr, uint16_t *val) +{ + int ret_val = 0; + uint16_t pkt_size; + + FM_LOG_DBG(D_CMD,"+%s(): [addr=0x%02x]\n", __func__, addr); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL, "%s(): get mutex failed\n", __func__); + ret_val = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL, "%s(): invalid tx_buf\n", __func__); + ret_val = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_get_reg(tx_buf, TX_BUF_SIZE, addr); + ret_val = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_FSPI_RD, SW_RETRY_CNT, FSPI_RD_TIMEOUT); + if(!ret_val){ + *val = fspi_rd; + } +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s(): [val=0x%02x]\n", __func__, fspi_rd); + return ret_val; +} + +/* + * MT6620_write + */ +int MT6620_write(uint8_t addr, uint16_t val) +{ + int ret_val = 0; + uint16_t pkt_size; + + FM_LOG_DBG(D_CMD,"+%s(): [addr=0x%02x]\n", __func__, addr); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret_val = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret_val = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + pkt_size = mt6620_set_reg(tx_buf, TX_BUF_SIZE, addr, val); + ret_val = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_FSPI_WR, SW_RETRY_CNT, FSPI_WR_TIMEOUT); +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s(): [addr=0x%02x]\n", __func__, addr); + return ret_val; +} + +int MT6620_set_bits(uint8_t addr, uint16_t bits, uint16_t mask) +{ + int ret = 0; + uint16_t val; + + FM_LOG_DBG(D_CMD,"+%s(): [addr=0x%02x],[bits=0x%04x],[mask=0x%04x]\n", __func__, addr, bits, mask); + ret = MT6620_read(addr, &val); + if (ret) + goto out; + + val = ((val & (mask)) | bits); + + ret = MT6620_write(addr, val); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +/* + * MT6620_Mute + * + * 1.Mute/Unmute audio, enable/disable rgf mute + * 2.Record mute status for FM recover context + */ +static int MT6620_Mute(bool mute) +{ + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():[mute=%d]\n", __func__, mute); + fm_cxt->rxcxt.mute = mute; + + if(mute){ + ret = MT6620_set_bits(0x9C, 0x0008, 0xFFF7); //1:9C D3 = 1 + }else{ + ret = MT6620_set_bits(0x9c, 0x0000, 0xFFF7); //1:9C D3 = 0 + } + + FM_LOG_NTC(D_CMD,"%s\n", mute ? "mute" : "unmute"); + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +/* + * MT6620_RampDown + * + * 1.Mute audio, enable rgf mute + * 2.Set softmute to fast mode + * 3.Clear all hw control requests + * + * Before return, we need check STC_DONE status flag (not the interrupt flag!) + * to ensure the sounds has now fully muted. + */ +static int MT6620_RampDown() +{ + int ret = 0; + uint16_t pkt_size = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_rampdown(tx_buf, TX_BUF_SIZE); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT); +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_RampDown_Tx() +{ + int ret = 0; + uint16_t pkt_size = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + pkt_size = mt6620_rampdown_tx(tx_buf, TX_BUF_SIZE); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_RAMPDOWN, SW_RETRY_CNT, RAMPDOWN_TIMEOUT); + +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_SetFreq(uint16_t freq) +{ + int ret = 0; + uint16_t pkt_size = 0; + + FM_LOG_DBG(D_CMD,"+%s():[freq=%d]\n", __func__, freq); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_tune_1(tx_buf, TX_BUF_SIZE, freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT); + Delayms(200); + pkt_size = mt6620_tune_2(tx_buf, TX_BUF_SIZE, freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT); + Delayms(35); + pkt_size = mt6620_tune_3(tx_buf, TX_BUF_SIZE, freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT); + _current_frequency = freq; + FM_LOG_NTC(D_CMD,"tune[freq=%d]\n", freq); +#ifdef CTP_CHECK_FM + tpd_get_fm_frequency(_current_frequency); +#endif + +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_Fast_SetFreq(uint16_t freq) +{ + int ret = 0; + uint16_t pkt_size = 0; + + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD, "%s(): get mutex failed\n", __func__); + return -ERR_GET_MUTEX; + } + + if(!tx_buf){ + FM_LOG_ERR(D_CMD, "%s():invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto release_mutex; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_fast_tune(tx_buf, TX_BUF_SIZE, freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT); + +release_mutex: + up(&fm_cmd_mutex); + return ret; +} + +static int MT6620_SetFreq_Tx(uint16_t freq) +{ + int ret = 0; + uint16_t pkt_size = 0; + + FM_LOG_DBG(D_CMD,"+%s():[freq=%d]\n", __func__, freq); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_tune_tx(tx_buf, TX_BUF_SIZE, freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT); + + Delayms(125); + _current_frequency = freq; + +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +/* +* MT6620_Seek +* pFreq: IN/OUT parm, IN start freq/OUT seek valid freq +* return true:seek success; false:seek failed +*/ +static int MT6620_Seek(uint16_t min_freq, uint16_t max_freq, uint16_t *pFreq, uint16_t seekdir, uint16_t space) +{ + int ret = 0; + uint16_t pkt_size = 0; + uint16_t startfreq = *pFreq; + + FM_LOG_DBG(D_CMD,"+%s():[startfreq=%d]\n", __func__, startfreq); + + if((ret = MT6620_RampDown())){ + FM_LOG_ERR(D_CMD|D_ALL,"%s():RampDown failed\n", __func__); + goto out1; + } + + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_seek_1(tx_buf, TX_BUF_SIZE, seekdir, space, max_freq, min_freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_SEEK | FLAG_SEEK_DONE, SW_RETRY_CNT, SEEK_TIMEOUT); + if(!ret){ + *pFreq = seek_result; + _current_frequency = seek_result; + FM_LOG_NTC(D_CMD,"seek[freq=%d]\n", seek_result); + Delayms(35); +#ifdef CTP_CHECK_FM + tpd_get_fm_frequency(_current_frequency); +#endif + }else{ + FM_LOG_WAR(D_CMD,"Rx Seek Failed\n"); + } + pkt_size = mt6620_seek_2(tx_buf, TX_BUF_SIZE, seekdir, space, max_freq, min_freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_SEEK, SW_RETRY_CNT, SEEK_TIMEOUT); +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_TxScan_SetFreq(uint16_t freq) +{ + int ret = 0; + uint16_t pkt_size = 0; + + FM_LOG_DBG(D_CMD,"+%s():[freq=%d]\n", __func__, freq); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_tune_txscan(tx_buf, TX_BUF_SIZE, freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_TUNE, SW_RETRY_CNT, TUNE_TIMEOUT); + + //Delayms(125); + _current_frequency = freq; +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_TxScan_GetCQI(int16_t *pRSSI, int16_t *pPAMD, int16_t *pMR) +{ + int cnt = 0; + int ret = 0; + int16_t tmp_reg = 0; + int16_t aRSSI = 0; + int16_t aPAMD = 0; + int16_t aMR = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((pRSSI == NULL) || (pPAMD == NULL) || (pMR == NULL)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s():para error, [pRSSI=%p],[aPAMD=%p],[pMR=%p]\n", + __func__, pRSSI, pPAMD, pMR); + ret = -ERR_INVALID_PARA; + goto out; + } + + for(cnt = 0; cnt < 8; cnt++){ + Delayms(3); + if((ret = MT6620_read(FM_ADDR_RSSI, &tmp_reg))) + goto out; + tmp_reg = tmp_reg&0x03ff; + tmp_reg = (tmp_reg > 511) ? ((int16_t)(tmp_reg-1024)) : tmp_reg; + aRSSI += tmp_reg; + + if((ret = MT6620_read(FM_ADDR_PAMD, &tmp_reg))) + goto out; + tmp_reg = tmp_reg&0x00ff; + tmp_reg = (tmp_reg > 127) ? ((int16_t)(tmp_reg-256)) : tmp_reg; + aPAMD += tmp_reg; + + if((ret = MT6620_read(FM_ADDR_MR, &tmp_reg))) + goto out; + tmp_reg = tmp_reg&0x01ff; + tmp_reg = (tmp_reg > 255) ? ((int16_t)(tmp_reg-512)) : tmp_reg; + aMR += tmp_reg; + } + + *pRSSI = aRSSI>>3; + *pPAMD = aPAMD>>3; + *pMR = aMR>>3; + + FM_LOG_DBG(D_CMD,"%s():[RSSI=%d],[PAMD=%d],[MR=%d]\n", + __func__, *pRSSI, *pPAMD, *pMR); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_TxScan_IsEmptyChannel(int16_t RSSI, int16_t PAMD, int16_t MR, int *empty) +{ + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():[RSSI=%d],[PAMD=%d],[MR=%d]\n", __func__, RSSI, PAMD, MR); + + if(empty == NULL){ + FM_LOG_DBG(D_CMD,"invalid pointer [empty=0x%x]!\n", (unsigned int)empty); + ret = -ERR_INVALID_PARA; + goto out; + } + + *empty = TRUE; + if(RSSI > FM_TXSCAN_RSSI_TH){ + *empty = FALSE; + goto out; + } + + if(PAMD < FM_TXSCAN_PAMD_TH){ + *empty = FALSE; + goto out; + } + + if(MR < FM_TXSCAN_MR_TH){ + *empty = FALSE; + goto out; + } + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_TxScan( + uint16_t min_freq, uint16_t max_freq, + uint16_t *pFreq, + uint16_t *pScanTBL, + uint16_t *ScanTBLsize, + uint16_t scandir, + uint16_t space) +{ + int ret = 0; + uint16_t freq = *pFreq; + uint16_t scan_cnt = *ScanTBLsize; + uint16_t cnt = 0; + int16_t rssi = 0; + int16_t pamd = 0; + int16_t mr = 0; + int counter = 0; + int empty = -1; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((!pScanTBL) || (*ScanTBLsize < TX_SCAN_MIN) || (*ScanTBLsize > TX_SCAN_MAX)){ + FM_LOG_ERR(D_CMD|D_ALL,"+%s():invalid scan table\n", __func__); + ret = -ERR_INVALID_PARA; + goto out; + } + + FM_LOG_DBG(D_CMD, "[freq=%d], [max_freq=%d],[min_freq=%d],[scan BTL size=%d],[scandir=%d],[space=%d]\n", + *pFreq, max_freq, min_freq, *ScanTBLsize, scandir, space); + + cnt = 0; + while(!(!(cnt < scan_cnt) || (freq > max_freq) || (freq < min_freq))){ + //MT6620_RampDown(); + //Set desired channel, tune to the channel, and perform fast AGC + counter++; //just for debug + + ret = MT6620_TxScan_SetFreq(freq); + if(ret){ + FM_LOG_ERR(D_CMD|D_ALL,"%s():set freq failed\n", __func__); + goto out; + } + + //wait 8~10ms for RF setting + Delayms(10); + //wait 4 AAGC period for AAGC setting, AAGC period = 1024/480k = 2.13ms + Delayms(9); + + ret = MT6620_TxScan_GetCQI(&rssi, &pamd, &mr); + if(ret){ + FM_LOG_ERR(D_CMD|D_ALL,"%s():get CQI failed\n", __func__); + goto out; + } + + ret = MT6620_TxScan_IsEmptyChannel(rssi, pamd, mr, &empty); + if(!ret){ + if((empty == TRUE) && ((freq < FMTX_SCAN_HOLE_LOW) || (freq > FMTX_SCAN_HOLE_HIGH))){ + *(pScanTBL + cnt) = freq; //strore the valid empty channel + cnt++; + FM_LOG_NTC(D_CMD|D_ALL,"empty channel:[freq=%d] [cnt=%d]\n", freq, cnt); + } + }else{ + FM_LOG_ERR(D_CMD|D_ALL,"%s():IsEmptyChannel failed\n", __func__); + goto out; + } + + if(scandir == SCAN_UP){ + if(freq == FMTX_SCAN_HOLE_LOW){ + freq += (FMTX_SCAN_HOLE_HIGH - FMTX_SCAN_HOLE_LOW + 1); + }else{ + freq += space; + } + }else if(scandir == SCAN_DOWN){ + if(freq == FMTX_SCAN_HOLE_HIGH){ + freq -= (FMTX_SCAN_HOLE_HIGH - FMTX_SCAN_HOLE_LOW + 1); + }else{ + freq -= space; + } + }else{ + FM_LOG_ERR(D_CMD|D_ALL,"%s():scandir para error\n", __func__); + ret = -ERR_INVALID_PARA; + goto out; + } + } + + *ScanTBLsize = cnt; + *pFreq = *(pScanTBL + cnt); + FM_LOG_DBG(D_CMD, "completed, [cnt=%d],[freq=%d],[counter=%d]\n", cnt, freq, counter); + FM_LOG_INF(D_CMD, "--time end[%d]\n", jiffies_to_msecs(jiffies)); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +/* + * MT6620_Scan + * + * Steps: + * 1.We should mute FM, and clear all hw control requests, so do Ramp_Down + * 2.Set scan direction, channel spacing + * (If need, set scan lower and upper Freq before step 3) + * 3.Enable hardware controlled scanning sequence + * 4.Check STC_DONE interrupt status flag, then clear the STC_DONE interrupt status flag + * 5.Read back channel scan bit_map information + * (IF need sorting by RSSI jump to Get RSSI after scan page) + * 6.Disable mute, Set softmute to normal mode. + */ +static int MT6620_Scan( + uint16_t min_freq, uint16_t max_freq, + uint16_t *pFreq, + uint16_t *pScanTBL, + uint16_t *ScanTBLsize, + uint16_t scandir, + uint16_t space) +{ + int ret = 0; + uint16_t pkt_size = 0; + uint16_t offset = 0; + uint16_t tmp_scanTBLsize = *ScanTBLsize; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((!pScanTBL) || (tmp_scanTBLsize < MT6620_SCANTBL_SIZE)){ + FM_LOG_ERR(D_ALL,"+%s():invalid scan table\n", __func__); + ret = -ERR_INVALID_PARA; + goto out1; + } + + FM_LOG_INF(D_CMD, "[freq=%d], [max_freq=%d],[min_freq=%d],[scan BTL size=%d],[scandir=%d],[space=%d]\n", + *pFreq, max_freq, min_freq, *ScanTBLsize, scandir, space); + if(tmp_scanTBLsize > MT6620_SCANTBL_SIZE){ + tmp_scanTBLsize = MT6620_SCANTBL_SIZE; + } + + MT6620_RampDown(); + + //Clear "FLAG_SCAN" & "FLAG_SCAN_DONE" to make sure we do make a new scan + spin_lock(&flag_lock); + flag &= ~(FLAG_SCAN | FLAG_SCAN_DONE); + spin_unlock(&flag_lock); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_scan_1(tx_buf, TX_BUF_SIZE, scandir, space, max_freq, min_freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_SCAN | FLAG_SCAN_DONE, SW_RETRY_CNT, SCAN_TIMEOUT); + if(!ret){ + memcpy(pScanTBL, scan_result, sizeof(uint16_t)*MT6620_SCANTBL_SIZE); + FM_LOG_INF(D_CMD,"Rx Scan Result:\n"); + for(offset = 0; offset < tmp_scanTBLsize; offset++){ + FM_LOG_INF(D_CMD,"%d: %04x\n", (int)offset, *(pScanTBL+offset)); + } + *ScanTBLsize = tmp_scanTBLsize; + Delayms(35); + }else{ + FM_LOG_WAR(D_CMD,"Rx Scan Failed\n"); + } + pkt_size = mt6620_scan_2(tx_buf, TX_BUF_SIZE, scandir, space, max_freq, min_freq); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_SCAN, SW_RETRY_CNT, SCAN_TIMEOUT); +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_ScanForceStop() +{ + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + spin_lock(&flag_lock); + flag |= FLAG_SCAN_DONE; + spin_unlock(&flag_lock); + memset(scan_result, 0, sizeof(uint16_t) * MT6620_SCANTBL_SIZE); + FM_LOG_DBG(D_CMD,"[flag=0x%08x]\n", flag); + wake_up(&fm_wq); + + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_GetCurRSSI(int *pRSSI) +{ + uint16_t tmp_reg; + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((ret = MT6620_read(FM_ADDR_RSSI, &tmp_reg))) + goto out; + FM_LOG_DBG(D_CMD,"[addr=0x%02x],[val=0x%04x]\n",\ + FM_ADDR_RSSI, tmp_reg); + + tmp_reg = tmp_reg&0x03ff; + //RS=RSSI + //If RS>511, then RSSI(dBm)= (RS-1024)/16*6 + // else RSSI(dBm)= RS/16*6 + // dBm + if (pRSSI){ + *pRSSI = (tmp_reg>511) ? (((tmp_reg-1024)*6)>>4):((tmp_reg*6)>>4); + } + FM_LOG_DBG(D_CMD,"[RSSI=%d]\n", *pRSSI); +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_SetVol(uint8_t vol) +{ + int ret = 0; + uint8_t tmp_vol = vol&0x3f; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if(tmp_vol > FM_VOL_MAX) + tmp_vol = FM_VOL_MAX; + + if((ret = MT6620_set_bits(0x9C, (tmp_vol<<8), 0xC0FF))) + goto out; + FM_LOG_DBG(D_CMD,"[vol=%d]\n", tmp_vol); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_GetVol(uint8_t *pVol) +{ + uint16_t tmp_reg; + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((ret = MT6620_read(0x9C, &tmp_reg))) + goto out; + + *pVol = (tmp_reg>>8) & 0x3f; + FM_LOG_DBG(D_CMD,"[vol=%d]\n", *pVol); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + + +/*********************************************************** +Function: MT6620_I2S_Setting() + +Description: set the I2S state on MT6620 + +Para: onoff--->I2S on/off + mode--->I2S mode: Master or Slave + +Return: 0, if success; error code, if failed +***********************************************************/ +static int MT6620_I2S_Setting(int onoff, int mode, int sample) +{ + uint16_t tmp_state = 0; + uint16_t tmp_mode = 0; + uint16_t tmp_sample = 0; + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if(onoff == FM_I2S_ON){ + tmp_state = 0x01; //I2S Frequency tracking on + }else if(onoff == FM_I2S_OFF){ + tmp_state = 0x00; //I2S Frequency tracking off + }else{ + FM_LOG_ERR(D_CMD|D_ALL,"%s():[onoff=%d]\n", __func__, onoff); + ret = -ERR_INVALID_PARA; + goto out; + } + + if(mode == FM_I2S_MASTER){ + tmp_mode = 0x03; //6620 as I2S master + }else if(mode == FM_I2S_SLAVE){ + tmp_mode = 0x0B; //6620 as I2S slave + }else{ + FM_LOG_ERR(D_CMD|D_ALL,"%s():[mode=%d]\n", __func__, mode); + ret = -ERR_INVALID_PARA; + goto out; + } + + if(sample == FM_I2S_32K){ + tmp_sample = 0x0000; //6620 I2S 32KHz sample rate + }else if(sample == FM_I2S_44K){ + tmp_sample = 0x0800; //6620 I2S 44.1KHz sample rate + }else if(sample == FM_I2S_48K){ + tmp_sample = 0x1000; //6620 I2S 48KHz sample rate + }else{ + FM_LOG_ERR(D_CMD|D_ALL,"%s():[sample=%d]\n", __func__, sample); + ret = -ERR_INVALID_PARA; + goto out; + } + if((ret = MT6620_set_bits(0x5F, tmp_sample, 0xE7FF))) + goto out; + if((ret = MT6620_write(0x9B, tmp_mode))) + goto out; + if((ret = MT6620_write(0x56, tmp_state))) + goto out; + + FM_LOG_NTC(D_CMD,"[onoff=%s][mode=%s][sample=%d](0)33KHz,(1)44.1KHz,(2)48KHz\n", + (onoff == FM_I2S_ON) ? "On" : "Off", + (mode == FM_I2S_MASTER) ? "Master" : "Slave", + sample); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_FMOverBT(int enable) +{ + int ret = 0; + static uint16_t state = 0; + static uint16_t mode = 0; + static uint16_t sample = 0; + static uint16_t inited = false; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + if(inited == false){ + // record priv val + if((ret = MT6620_read(0x56, &state))) + goto out; + if((ret = MT6620_read(0x9B, &mode))) + goto out; + if((ret = MT6620_read(0x5F, &sample))) + goto out; + inited = true; + FM_LOG_NTC(D_MAIN,"init, record priv seetings\n"); + } + + if(enable == TRUE){ + //disable analog output when FM over BT + if((ret = MT6620_set_bits(0x3A, 0, MASK(2)))) + goto out; + //set FM over BT + if((ret = MT6620_write(0x56, 0x0001))) + goto out; + if((ret = MT6620_write(0x9B, 0x000b))) + goto out; + if((ret = MT6620_write(0x5F, 0x1175))) + goto out; + FM_LOG_NTC(D_MAIN,"set FM via BT controller\n"); + }else if(enable == FALSE){ + //enable analog output when FM normal mode + if((ret = MT6620_set_bits(0x3A, BITn(2), MASK(2)))) + goto out; + //recover to priv val + if((ret = MT6620_write(0x56, state))) + goto out; + if((ret = MT6620_write(0x9B, mode))) + goto out; + if((ret = MT6620_write(0x5F, sample))) + goto out; + FM_LOG_NTC(D_MAIN,"set FM via Host\n"); + }else{ + FM_LOG_ERR(D_CMD|D_ALL,"%s()\n", __func__); + ret = -ERR_INVALID_PARA; + goto out; + } +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_ANA_SWITCH(int antenna) +{ + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + FM_LOG_NTC(D_CMD,"Switch to %s atenna\n", (antenna == FM_LONG_ANA) ? "Long" : "Short"); + if(antenna == FM_LONG_ANA){ + //Long Antenna RSSI threshold, 0xE0 D0~D9 + if((ret = MT6620_write(0xE0, ((0xA301 & 0xFC00) | (FMR_RSSI_TH_LONG & 0x03FF))))) + goto out; + //Turn on Short Antenna LNA and Off TR Switch + if((ret = MT6620_write(0x04, 0x0142))) + goto out; + //Turn off the Short Antenna Capbank biasing + if((ret = MT6620_write(0x05, 0x00E7))) + goto out; + //Turn off the Short Antenna Capbank biasing + if((ret = MT6620_write(0x26, 0x0004))) + goto out; + //Disable concurrent calibration for VCO and SCAL + if((ret = MT6620_write(0x2E, 0x0008))) + goto out; + }else if(antenna == FM_SHORT_ANA){ + //Short Antenna RSSI threshold, 0xE0 D0~D9 + if((ret = MT6620_write(0xE0, ((0xA2E0 & 0xFC00) | (FMR_RSSI_TH_SHORT & 0x03FF))))) + goto out; + //Turn on Short Antenna LNA and TR Switch + if((ret = MT6620_write(0x04, 0x0145))) + goto out; + //Turn on the Short Antenna Capbank biasing + if((ret = MT6620_write(0x05, 0x00FF))) + goto out; + //Turn on the Short Antenna Capbank biasing + if((ret = MT6620_write(0x26, 0x0024))) + goto out; + //Enable concurrent calibration for VCO and SCAL + if((ret = MT6620_write(0x2E, 0x0000))) + goto out; + }else{ + FM_LOG_ERR(D_CMD|D_ALL,"%s()\n", __func__); + ret = -ERR_INVALID_PARA; + goto out; + } +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +#ifdef FMDEBUG +static int MT6620_dump_reg(void) +{ + int i; + int ret = 0; + uint16_t val; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0001))) + goto out; + for (i = 0; i < MT6620_SCANTBL_SIZE; i++){ + val = 0; + ret = MT6620_read(FM_MAIN_BITMAP0+i, &val); + if (ret == 0){ + FM_LOG_DBG(D_CMD,"%2d\t%04x\n", i, val); + }else{ + FM_LOG_DBG(D_CMD|D_ALL,"%2d\tXXXX\n", i); + goto out; + } + } + ret = MT6620_write(FM_MAIN_PGSEL, 0x0); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} +#endif // FMDEBUG + +static int MT6620_GetMonoStereo(uint16_t *pMonoStereo) +{ + uint16_t tmp_reg; + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + + if((ret = MT6620_read(0xF8, &tmp_reg))) + goto out; + + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + + tmp_reg = (tmp_reg&0x400)>>10; + if(!tmp_reg){ + tmp_reg = 1; + }else{ + tmp_reg = 0; + } + *pMonoStereo = tmp_reg;//0:stereo, 1:mono + FM_LOG_DBG(D_CMD,"[MonoStereo=%d]\n", *pMonoStereo); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +/* + * MT6620_SetMonoStereo + * Force set to stero/mono mode + * @MonoStereo -- 0, auto; 1, force mono + * If success, return 0; else error code + */ +static int MT6620_SetMonoStereo(int MonoStereo) +{ + uint16_t tmp_reg; + int ret = 0; + + if((ret = MT6620_write(FM_MAIN_PGSEL, FM_PG1))) + goto out; + + tmp_reg = MonoStereo ? BITn(1) : 0; //MonoStereo, 1: force mono; 0:auto + if((ret = MT6620_set_bits(FM_STEROMONO_CTR, tmp_reg, MASK(1))))//set E0 D1=0 + goto out; + + if((ret = MT6620_write(FM_MAIN_PGSEL, FM_PG0))) + goto out; + + FM_LOG_DBG(D_CMD,"set to %s\n", MonoStereo ? "auto" : "force mono"); + +out: + return ret; +} + +static int MT6620_GetCapArray(int *caparray) +{ + uint16_t tmp_reg; + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + + if((ret = MT6620_read(0x26, &tmp_reg))) + goto out; + + *caparray = (int)tmp_reg; + FM_LOG_DBG(D_CMD,"[caparray=%d]\n", *caparray); + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_GetCurPamd(uint16_t *pPamdLevl) +{ + uint16_t tmp_reg; + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():\n", __func__); + if((ret = MT6620_read(0xE9, &tmp_reg))) + goto out; + tmp_reg &= 0x00FF; + /*PA=PAMD + *If PA>511 then PAMD(dB)= (PA-1024)/16*6, + * else PAMD(dB)=PA/16*6 + */ + *pPamdLevl = (tmp_reg>127) ? ((256-tmp_reg)*6/16):0; + +out: + FM_LOG_DBG(D_CMD,"[PamdLevl=%d]\n", (int)*pPamdLevl); + return ret; +} + +static int MT6620_em_test(uint16_t group_idx, uint16_t item_idx, uint32_t item_value) +{ + int ret = 0; + + FM_LOG_DBG(D_CMD,"+%s():[group_idx=%d],[item_idx=%d],[item_value=%d]\n", + __func__, group_idx, item_idx, item_value); + + switch (group_idx){ + case mono: + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + + if(item_value == 1){ + if((ret = MT6620_set_bits(0xE0, 0x02, 0xFFFF))) + goto out; + }else{ + if((ret = MT6620_set_bits(0xE0, 0x0, 0xFFFD))) + goto out; + } + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + break; + case stereo: + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + if(item_value == 0){ + if((ret = MT6620_set_bits(0xE0, 0x0, 0xFFFD))) + goto out; + }else{ + switch (item_idx){ + case Sblend_ON: + if((ret = MT6620_set_bits(0xD8, item_idx<<15, 0x7FFF))) + goto out; + break; + case Sblend_OFF: + if((ret = MT6620_set_bits(0xD8, 0, 0x7FFF))) + goto out; + break; + } + } + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + break; + case RSSI_threshold: + if((ret = MT6620_set_bits(0xe0, item_value, 0xFC00))) + goto out; + break; + case HCC_Enable: + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + if(item_idx){ + if((ret = MT6620_set_bits(0xCF, 0x10, 0xFFFF))) + goto out; + }else{ + if((ret = MT6620_set_bits(0xCF, 0x0, 0xFFEF))) + goto out; + } + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + break; + case PAMD_threshold: + if((ret = MT6620_set_bits(0xE1, item_value, 0xFF00))) + goto out; + break; + case Softmute_Enable: + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + if(item_idx){ + if((ret = MT6620_set_bits(0xCF, 0x0020, 0xFFFF))) //1:CF[5] = 1 + goto out; + }else{ + if((ret = MT6620_set_bits(0xCF, 0x0000, 0xFFDF))) //1:CF[5] = 0 + goto out; + } + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + break; + case De_emphasis: + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + if(item_idx == 2){ + if((ret = MT6620_set_bits(0xd4, 0x2000, 0xCFFF))) + goto out; + }else if(item_idx == 1){ + if((ret = MT6620_set_bits(0xd4, 0x1000, 0xCFFF))) + goto out; + }else if(item_idx == 0){ + if((ret = MT6620_set_bits(0xd4, 0x0000, 0xCFFF))) + goto out; + } + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + break; + case HL_Side: + if(item_idx == 2){ + //H-Side + if((ret = MT6620_set_bits(0xCB, 0x11, 0xFFFE))) + goto out; + if((ret = MT6620_set_bits(0xF, 0x0400, 0xFBFF))) + goto out; + }else if(item_idx == 1){ + //L-Side + if((ret = MT6620_set_bits(0xCB, 0x10, 0xFFFE))) + goto out; + if((ret = MT6620_set_bits(0xF, 0x0, 0xFBFF))) + goto out; + } + break; + + case Dynamic_Limiter: + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + if(item_idx){ + if((ret = MT6620_set_bits(0xFA, 0x0, 0xFFF7))) + goto out; + }else{ + if((ret = MT6620_set_bits(0xFA, 0x08, 0xFFF7))) + goto out; + } + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + break; + + case Softmute_Rate: + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x01))) + goto out; + if((ret = MT6620_set_bits(0xc8, item_value<<8, 0x80FF))) + goto out; + if((ret = MT6620_write(FM_MAIN_PGSEL, 0x0))) + goto out; + break; + + case AFC_Enable: + if (item_idx){ + if((ret = MT6620_set_bits(0x63, 0x0400, 0xFBFF))) + goto out; + }else{ + if((ret = MT6620_set_bits(0x63, 0x0, 0xFBFF))) + goto out; + } + break; + +#if 0 + case Softmute_Level: + MT6620_write(FM_MAIN_PGSEL, 0x01); + if(item_value > 0x24) + item_value = 0x24; + MT6620_set_bits(0xD1, item_value, 0xFFC0); + MT6620_write(FM_MAIN_PGSEL, 0x0); + break; +#endif + case Analog_Volume: + if((ret = MT6620_set_bits(0x9C, item_value<<8, 0xC0FF))) + goto out; + break; + + default: + break; + } + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_Rds_Tx_Enable(uint8_t enable) +{ + int ret = 0; + + FM_LOG_NTC(D_CMD,"+%s(): %s\n", __func__, enable ? "Enable" : "Disable"); + + if(enable == 1){ + if((ret = MT6620_write(0x9F, 0x0000))) + goto out; + if((ret = MT6620_write(0xAB, 0x3872))) + goto out; + if((ret = MT6620_write(0xAC, 0x3B3A))) + goto out; + if((ret = MT6620_write(0xAD, 0x0113))) + goto out; + if((ret = MT6620_write(0xAE, 0x03B2))) + goto out; + if((ret = MT6620_write(0xAF, 0x0001))) + goto out; + if((ret = MT6620_write(0xB1, 0x63EB))) + goto out; + if((ret = MT6620_write(0xF4, 0x0020))) + goto out; + if((ret = MT6620_write(0xF5, 0x3222))) + goto out; + }else{ + if((ret = MT6620_write(0x9F, 0x0000))) + goto out; + if((ret = MT6620_write(0xAB, 0x39B6))) + goto out; + if((ret = MT6620_write(0xAC, 0x3C3E))) + goto out; + if((ret = MT6620_write(0xAD, 0x0000))) + goto out; + if((ret = MT6620_write(0xAE, 0x03C2))) + goto out; + if((ret = MT6620_write(0xAF, 0x0001))) + goto out; + if((ret = MT6620_write(0xF4, 0x0020))) + goto out; + if((ret = MT6620_write(0xF5, 0xBF16))) + goto out; + ret = MT6620_write(0xB1, 0x623D); + } + +out: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int MT6620_Rds_Tx(uint16_t pi, uint16_t *ps, uint16_t *other_rds, uint8_t other_rds_cnt) +{ + int ret = 0; + uint16_t pkt_size = 0; + + FM_LOG_DBG(D_CMD,"+%s():PI=0x%04x, PS=0x%04x/0x%04x/0x%04x, other_rds_cnt=%d \n", + __func__, pi, ps[0], ps[1], ps[2], other_rds_cnt); + FM_LOG_INF(D_CMD,"-fm_cmd_mutex\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL,"%s():get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out1; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_CMD|D_ALL,"%s():invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + pkt_size = mt6620_rds_tx(tx_buf, TX_BUF_SIZE, pi, ps, other_rds, other_rds_cnt); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_RDS_TX, SW_RETRY_CNT, RDS_TX_TIMEOUT); + +out: + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + +out1: + FM_LOG_DBG(D_CMD,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + +static int fm_enable_rds_BlerCheck(struct fm *fm) +{ + int ret = 0; + ret = down_interruptible(&fm_timer_mutex); + if(ret){ + FM_LOG_ERR(D_MAIN,"down fm_timer_mutex failed[ret=%d]\n", ret); + goto out; + } + timer_sys.rds_reset_en = FM_RDS_RST_ENABLE; + FM_LOG_DBG(D_TIMER,"enable RDS reset func\n"); + up(&fm_timer_mutex); + +out: + return ret; +} + +static int fm_disable_rds_BlerCheck() +{ + int ret = 0; + ret = down_interruptible(&fm_timer_mutex); + if(ret){ + FM_LOG_ERR(D_MAIN,"down fm_timer_mutex failed[ret=%d]\n", ret); + goto out; + } + timer_sys.rds_reset_en = FM_RDS_RST_DISABLE; + FM_LOG_DBG(D_TIMER,"disable RDS reset func\n"); + up(&fm_timer_mutex); + +out: + return ret; +} + +/* +************************************************************************************ +Function: fm_get_gps_rtc_info() + +Description: get GPS RTC drift info, and this function should not block + +Date: 2011/04/10 + +Return Value: success:0, failed: error coe +************************************************************************************ +*/ +static int fm_get_gps_rtc_info(struct fm_gps_rtc_info *dst, struct fm_gps_rtc_info *src) +{ + int ret = 0; + int retry_cnt = 0; + //struct fm *fm = (struct fm*)fm_cb; + + FMR_ASSERT(src); + FMR_ASSERT(dst); + + if(src->retryCnt > 0){ + dst->retryCnt = src->retryCnt; + FM_LOG_DBG(D_MAIN,"%s, new [retryCnt=%d]\n", __func__, dst->retryCnt); + } + if(src->ageThd > 0){ + dst->ageThd = src->ageThd; + FM_LOG_DBG(D_MAIN,"%s, new [ageThd=%d]\n", __func__, dst->ageThd); + } + if(src->driftThd > 0){ + dst->driftThd = src->driftThd; + FM_LOG_DBG(D_MAIN,"%s, new [driftThd=%d]\n", __func__, dst->driftThd); + } + if(src->tvThd.tv_sec > 0){ + dst->tvThd.tv_sec = src->tvThd.tv_sec; + FM_LOG_DBG(D_MAIN,"%s, new [tvThd=%d]\n", __func__, (int)dst->tvThd.tv_sec); + } + + while(down_trylock(&fm_rtc_mutex)){ + FM_LOG_WAR(D_MAIN,"down_trylock failed\n"); + if(++retry_cnt < dst->retryCnt){ + FM_LOG_WAR(D_MAIN,"[retryCnt=%d]\n", retry_cnt); + msleep_interruptible(50); + continue; + }else{ + FM_LOG_WAR(D_MAIN,"down_trylock retry failed\n"); + ret = -EFAULT; + goto out; + } + } + + dst->age = src->age; + dst->drift = src->drift; + dst->stamp = jiffies; //get curren time stamp + dst->flag = FM_GPS_RTC_INFO_NEW; + + up(&fm_rtc_mutex); + + /* + //send event to info fm_tx_rtc_ctrl_work + if(timer_sys.tx_rtc_ctrl_en == FM_TX_RTC_CTRL_ENABLE){ + FM_LOG_DBG(D_TIMER,"fm_tx_rtc_ctrl_work, ticks:%d\n", jiffies_to_msecs(jiffies)); + queue_work(fm->fm_timer_workqueue, &fm->fm_tx_rtc_ctrl_work); + } + */ + +out: + return ret; +} +static int fm_hw_reset(void) +{ + int ret = 0; + FM_LOG_DBG(D_MAIN,"+%s():\n", __func__); + + //check if we are resetting + if(subsys_rst_state != FM_SUBSYS_RST_OFF){ + FM_LOG_NTC(D_MAIN, "FM subsys resetting is ongoing!!!\n"); + goto out; + } + + //set rst state start + subsys_rst_state = FM_SUBSYS_RST_START; + + //disable FM timer + timer_sys.onoff = FM_TIMER_SYS_OFF; + + //wake up waiting wq, all flag set true, force all operations exit + spin_lock(&flag_lock); + flag = 0xFFFFFFFF; + spin_unlock(&flag_lock); + wake_up(&fm_wq); + + //FM subsys OFF + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM)){ + FM_LOG_ERR(D_MAIN,"WMT turn off FM fail!\n"); + ret = -ERR_STP; + }else{ + FM_LOG_NTC(D_MAIN,"WMT turn off FM OK!\n"); + } + + //change FM pwr state + fm_cb->powerup = FM_PWR_OFF; + fm_cb->chipon = false; + mtk_wcn_stp_register_event_cb(FM_TASK_INDX, NULL); + + //wake up recover work if need + queue_work(fm_cb->fm_timer_workqueue, &fm_cb->fm_subsys_recover_work); + +out: + FM_LOG_DBG(D_MAIN,"-%s():[ret=%d]\n", __func__, ret); + return ret; +} + + +//fm timer will timeout every sencod +static void fm_timer_func(unsigned long data) +{ + int ret = 0; + struct fm *fm = (struct fm*)fm_cb; + struct fm_timer_sys *timer = &timer_sys; + int vco_cycle = 1; + + if(!fm) + goto out; + if(!timer) + goto out; + //FM_LOG_DBG(D_TIMER,"+%s():\n", __func__); + ret = down_interruptible(&fm_timer_mutex); + if(ret){ + FM_LOG_ERR(D_MAIN,"down fm_timer_mutex failed[ret=%d]\n", ret); + goto out; + } + if (timer->onoff == FM_TIMER_SYS_OFF){ + up(&fm_timer_mutex); + goto out; + } + timer->count++; + + //FM_LOG_DBG(D_TIMER,"+T:%d\n", jiffies_to_msecs(jiffies)); + //schedule RDS reset work if need + if(g_fm_config.rdsrst < 1){ + FM_LOG_WAR(D_TIMER,"rds rst time err\n"); + g_fm_config.rdsrst = FM_RDS_RST_INVAL_MIN; + } + if((timer->rds_reset_en == FM_RDS_RST_ENABLE) && (timer->count%g_fm_config.rdsrst == 0)){ + FM_LOG_DBG(D_TIMER,"fm_rds_reset_work, ticks:%d\n", jiffies_to_msecs(jiffies)); + queue_work(fm->fm_timer_workqueue, &fm->fm_rds_reset_work); + } + //schedule tx pwr ctrl work if need + if(g_fm_config.txpwrctl < 1){ + FM_LOG_WAR(D_TIMER,"tx power ctl time err\n"); + g_fm_config.txpwrctl = FM_TX_PWR_CTRL_INVAL_MIN; + } + if((timer->tx_pwr_ctrl_en == FM_TX_PWR_CTRL_ENABLE) && (timer->count%g_fm_config.txpwrctl == 0)){ + FM_LOG_DBG(D_TIMER,"fm_tx_power_ctrl_work, ticks:%d\n", jiffies_to_msecs(jiffies)); + queue_work(fm->fm_timer_workqueue, &fm->fm_tx_power_ctrl_work); + } + /* + //schedule tx RTC ctrl work if need + if((timer->tx_rtc_ctrl_en == FM_TX_RTC_CTRL_ENABLE)&& (timer->count%FM_TX_RTC_CTRL_INTERVAL == 0)){ + FM_LOG_DBG(D_TIMER,"fm_tx_rtc_ctrl_work, ticks:%d\n", jiffies_to_msecs(jiffies)); + queue_work(fm->fm_timer_workqueue, &fm->fm_tx_rtc_ctrl_work); + }*/ + //schedule tx desense with wifi/bt work if need + if(g_fm_config.vcooff < 1){ + FM_LOG_WAR(D_TIMER,"vco tracking time err\n"); + g_fm_config.vcooff = FM_TX_VCO_OFF_MIN; + } + vco_cycle = g_fm_config.vcooff + g_fm_config.vcoon/1000; + if((timer->tx_desense_en == FM_TX_DESENSE_ENABLE) && (timer->count%vco_cycle == 0)){ + FM_LOG_DBG(D_TIMER,"fm_tx_desense_wifi_work, ticks:%d\n", jiffies_to_msecs(jiffies)); + queue_work(fm->fm_timer_workqueue, &fm->fm_tx_desense_wifi_work); + } + up(&fm_timer_mutex); + + //update timer + if(g_fm_config.timer < 1000){ + FM_LOG_WAR(D_TIMER,"timersys time err\n"); + g_fm_config.timer = FM_TIMER_TIMEOUT_MIN; + } + mod_timer(&fm_timer, jiffies + g_fm_config.timer/(1000/HZ)); + FM_LOG_DBG(D_TIMER,"-T:%d,mod timer\n", jiffies_to_msecs(jiffies)); + +out: + //FM_LOG_DBG(D_TIMER,"-%s():[onoff=%d]\n", __func__, timer->onoff); + return; +} +static void fm_tx_rtc_ctrl_worker_func(struct work_struct *work) +{ + int ret = 0; + int ctrl = 0; + struct fm_gps_rtc_info rtcInfo; + //struct timeval curTime; + //struct fm *fm = (struct fm*)fm_cb; + unsigned long curTime = 0; + + FM_LOG_DBG(D_TIMER,"+%s():\n", __func__); + + ret = down_interruptible(&fm_rtc_mutex); + if(ret){ + FM_LOG_ERR(D_MAIN,"down fm_rtc_mutex failed[ret=%d]\n", ret); + goto out; + } + + if(gps_rtc_info.flag == FM_GPS_RTC_INFO_NEW){ + memcpy(&rtcInfo, &gps_rtc_info, sizeof(struct fm_gps_rtc_info)); + gps_rtc_info.flag = FM_GPS_RTC_INFO_OLD; + up(&fm_rtc_mutex); + }else{ + FM_LOG_DBG(D_MAIN,"there's no new rtc drift info\n"); + up(&fm_rtc_mutex); + goto out; + } + + if(rtcInfo.age > rtcInfo.ageThd){ + FM_LOG_WAR(D_MAIN,"age over it's threshlod\n"); + goto out; + } + if((rtcInfo.drift <= rtcInfo.driftThd) && (rtcInfo.drift >= -rtcInfo.driftThd)){ + FM_LOG_WAR(D_MAIN,"drift over it's MIN threshlod\n"); + goto out; + } + + if(rtcInfo.drift > FM_GPS_RTC_DRIFT_MAX){ + FM_LOG_WAR(D_MAIN,"drift over it's +MAX threshlod\n"); + rtcInfo.drift = FM_GPS_RTC_DRIFT_MAX; + goto out; + }else if(rtcInfo.drift < -FM_GPS_RTC_DRIFT_MAX){ + FM_LOG_WAR(D_MAIN,"drift over it's -MAX threshlod\n"); + rtcInfo.drift = -FM_GPS_RTC_DRIFT_MAX; + goto out; + } + /* + //get current time + do_gettimeofday(&curTime); + if((curTime.tv_sec - rtcInfo.tv.tv_sec) > rtcInfo.tvThd.tv_sec){ + FM_LOG_WAR(D_MAIN,"time diff over it's threshlod\n"); + goto out; + }*/ + curTime = jiffies; + if(((long)curTime - (long)rtcInfo.stamp)/HZ > rtcInfo.tvThd.tv_sec){ + FM_LOG_WAR(D_MAIN,"time diff over it's threshlod\n"); + goto out; + } + if(priv.state == INITED){ + FM_LOG_INF(D_TIMER,"%s, RTC_drift_ctrl[0x%08x]\n", __func__, (unsigned int)priv.priv_tbl.rtc_drift_ctrl); + if(priv.priv_tbl.rtc_drift_ctrl != NULL){ + ctrl = rtcInfo.drift; + if((ret = priv.priv_tbl.rtc_drift_ctrl(_current_frequency, &ctrl))) + goto out; + } + } +out: + FM_LOG_DBG(D_TIMER,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return; +} + +static void fm_tx_power_ctrl_worker_func(struct work_struct *work) +{ + int ret = 0; + int ctrl = 0; + struct fm *fm = (struct fm*)fm_cb; + + FM_LOG_DBG(D_TIMER,"+%s():\n", __func__); + + if(down_interruptible(&fm_rxtx_mutex)){ + FM_LOG_ERR(D_TIMER, "%s(): get rx/tx mutex failed\n", __func__); + return; + } + + if(!fm){ + FM_LOG_ERR(D_TIMER,"err, [fm=0x%08x]\n", (int)fm); + goto out; + } + + if(fm->powerup != FM_PWR_TX_ON){ + FM_LOG_NTC(D_TIMER,"FM is not on TX mode\n"); + goto out; + } + + if(priv.state == INITED){ + if(priv.priv_tbl.tx_pwr_ctrl != NULL){ + ctrl = fm->tx_pwr; + FM_LOG_INF(D_TIMER,"tx pwr %ddb\n", ctrl); + if((ret = priv.priv_tbl.tx_pwr_ctrl(_current_frequency, &ctrl))) + goto out; + } + } + +out: + up(&fm_rxtx_mutex); + FM_LOG_DBG(D_TIMER,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return; +} + +static void fm_tx_desense_wifi_worker_func(struct work_struct *work) +{ + int ret = 0; + int ctrl = 0; + struct fm *fm = (struct fm*)fm_cb; + + FM_LOG_DBG(D_TIMER,"+%s():\n", __func__); + + if(down_interruptible(&fm_rxtx_mutex)){ + FM_LOG_ERR(D_TIMER, "%s(): get rx/tx mutex failed\n", __func__); + return; + } + + if(!fm){ + FM_LOG_ERR(D_TIMER,"err, [fm=0x%08x]\n", (int)fm); + goto out; + } + + if(fm->powerup != FM_PWR_TX_ON){ + FM_LOG_NTC(D_TIMER,"FM is not on TX mode\n"); + goto out; + } + + fm_tx_rtc_ctrl_worker_func(work); + + ctrl = g_fm_config.vcoon; + if(priv.state == INITED){ + FM_LOG_INF(D_TIMER,"%s, tx_desense_wifi[0x%08x]\n", __func__, (unsigned int)priv.priv_tbl.tx_desense_wifi); + if(priv.priv_tbl.tx_desense_wifi != NULL){ + if((ret = priv.priv_tbl.tx_desense_wifi(_current_frequency, &ctrl))) + goto out; + } + } + +out: + up(&fm_rxtx_mutex); + FM_LOG_DBG(D_TIMER,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return; +} + +static void fm_rds_reset_worker_func(struct work_struct *work) +{ + struct fm *fm = fm_cb; + int ret = 0; + + FM_LOG_DBG(D_TIMER,"+%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + + if(down_interruptible(&fm_rxtx_mutex)){ + FM_LOG_ERR(D_TIMER, "%s(): get rx/tx mutex failed\n", __func__); + return; + } + + if(!fm){ + FM_LOG_ERR(D_TIMER,"err, [fm=0x%08x]\n", (int)fm); + goto out; + } + + if(fm->powerup != FM_PWR_RX_ON){ + FM_LOG_NTC(D_TIMER,"FM is not on RX mode\n"); + goto out; + } + + FM_LOG_INF(D_TIMER,"%s():-fm_read_mutex\n", __func__); + if (down_interruptible(&fm_read_mutex)){ + FM_LOG_ERR(D_ALL,"fm_rds_reset_worker_func can't get mutex"); + goto out; + } + + ret = MT6620_RDS_BlerCheck(fm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_TIMER|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_read_mutex); + FM_LOG_INF(D_TIMER,"%s():+fm_read_mutex\n", __func__); + +out: + up(&fm_rxtx_mutex); + FM_LOG_DBG(D_TIMER,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return; +} + +void stp_rx_event_cb(void) +{ + struct fm *fm = fm_cb; + static int cnt1 = 0; + queue_work(fm->fm_workqueue, &fm->fm_rx_work); + FM_LOG_DBG(D_MAIN,"cnt1=%d\n", ++cnt1); + FM_LOG_DBG(D_MAIN,"%s()\n", __func__); +} + +static void fm_wholechip_rst_cb(ENUM_WMTDRV_TYPE_T src, + ENUM_WMTDRV_TYPE_T dst, + ENUM_WMTMSG_TYPE_T type, + void *buf, + unsigned int sz) +{ + int ret = 0; + //To handle reset procedure please + ENUM_WMTRSTMSG_TYPE_T rst_msg; + + FM_LOG_DBG(D_MAIN,"+%s()\n", __func__); + if(sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)){ + memcpy((char *)&rst_msg, (char *)buf, sz); + FM_LOG_DBG(D_MAIN, "[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_FM) && (type == WMTMSG_TYPE_RESET)){ + if(rst_msg == WMTRSTMSG_RESET_START){ + FM_LOG_NTC(D_MAIN, "FM restart start!\n"); + /*reset_start message handling*/ + //check if we are resetting + if(chip_rst_state != FM_WHOLECHIP_RST_OFF){ + FM_LOG_NTC(D_MAIN, "FM resetting is ongoing!!!\n"); + return; + } + + //set rst state start + chip_rst_state = FM_WHOLECHIP_RST_START; + + //Record current context + + //disable FM timer + ret = down_interruptible(&fm_timer_mutex); + if(ret){ + FM_LOG_WAR(D_MAIN, "down fm_timer_mutex failed!\n"); + //FIX ME, how to handle this case? + return; + }else{ + timer_sys.onoff = FM_TIMER_SYS_OFF; + up(&fm_timer_mutex); + } + + //wake up waiting wq, all flag set true, force all operations exit + spin_lock(&flag_lock); + flag = 0xFFFFFFFF; + spin_unlock(&flag_lock); + wake_up(&fm_wq); + + //change FM pwr state + ret = down_interruptible(&fm_ops_mutex); + if(ret){ + FM_LOG_WAR(D_MAIN, "down fm_ops_mutex failed!\n"); + //FIX ME, how to handle this case? + return; + }else{ + fm_cb->powerup = FM_PWR_OFF; + fm_cb->chipon = false; + up(&fm_ops_mutex); + } + + //Unregister FM main Callback + mtk_wcn_stp_register_event_cb(FM_TASK_INDX, NULL); + } else if(rst_msg == WMTRSTMSG_RESET_END){ + FM_LOG_NTC(D_MAIN, "FM restart end!\n"); + /*reset_end message handling*/ + //check if we have get start event + if(chip_rst_state != FM_WHOLECHIP_RST_START){ + FM_LOG_NTC(D_MAIN, "Wrong event, there's no start!!!\n"); + return; + } + + //set all event flag false + spin_lock(&flag_lock); + flag = 0x0; + spin_unlock(&flag_lock); + + //wake up recover work if need + queue_work(fm_cb->fm_timer_workqueue, &fm_cb->fm_rst_recover_work); + + //set rst state end + chip_rst_state = FM_WHOLECHIP_RST_END; + } + } + } else { + /*message format invalid*/ + FM_LOG_WAR(D_MAIN, "message format invalid!\n"); + } +} + +static int fm_recover_func(struct fm *fm, struct fm_context *cxt) +{ + int ret = 0; + struct fm_tune_parm parm; + + FM_LOG_NTC(D_MAIN,"+%s():\n", __func__); + if(cxt->ref < 1){ + FM_LOG_NTC(D_MAIN,"FM not in use, no need recover\n"); + goto out; + }else{ + //FM func on + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM)){ + FM_LOG_WAR(D_MAIN, "FM mtk_wcn_wmt_func_on failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + + //change FM Subsys state + ret = down_interruptible(&fm_ops_mutex); + if(ret){ + FM_LOG_WAR(D_MAIN, "down fm_ops_mutex failed!\n"); + //FIX ME, how to handle this case? + goto out; + }else{ + fm->chipon = true; + up(&fm_ops_mutex); + } + + //Register FM main Callback + mtk_wcn_stp_register_event_cb(FM_TASK_INDX, stp_rx_event_cb); + + //Check stp ready after turn on function + if(FALSE == mtk_wcn_stp_is_ready()){ + FM_LOG_ERR(D_ALL,"6620 stp is not ready, please retry later\n"); + goto out; + } + + //power on FM, recover the context + switch(cxt->powerup){ + case FM_PWR_RX_ON: + fm_powerdown(fm, FM_RX); + //power on FM RX + parm.band = fm->band; + parm.freq = cxt->freq; + parm.space = FM_SPACE_100K; + ret = fm_powerup(fm, &parm); + FM_LOG_NTC(D_MAIN, "[band=%d][freq=%d]\n", parm.band, parm.freq); + if(ret){ + FM_LOG_WAR(D_MAIN, "fm_powerup failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + + /*//set FM RX vol + ret = fm_setvol(fm, cxt->rxcxt.vol); + if(ret){ + FM_LOG_WAR(D_MAIN, "fm_setvol failed!\n"); + //FIX ME, how to handle this case? + goto out; + }*/ + //set mute if need + FM_LOG_NTC(D_MAIN, "[rxcxt.mute=%d]\n", cxt->rxcxt.mute); + ret = MT6620_Mute(cxt->rxcxt.mute); + if(ret){ + FM_LOG_WAR(D_MAIN, "MT6620_Mute failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + + //set FM antenna type + FM_LOG_NTC(D_MAIN, "[rxcxt.ana=%d]\n", cxt->rxcxt.ana); + ret = fm_antenna_switch(fm, cxt->rxcxt.ana); + if(ret){ + FM_LOG_WAR(D_MAIN, "fm_antenna_switch failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + + //set FM over bt + FM_LOG_NTC(D_MAIN, "[rxcxt.ViaBt=%d]\n", cxt->rxcxt.ViaBt); + ret = fm_over_bt(fm, cxt->rxcxt.ViaBt); + if(ret){ + FM_LOG_WAR(D_MAIN, "fm_over_bt failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + + //set FM RDS on/off + FM_LOG_NTC(D_MAIN, "[rxcxt.rdsOn=%d]\n", cxt->rxcxt.rdsOn); + cxt->rxcxt.rdsOn = true; //XHC. just for test + if(fm_cxt->rxcxt.rdsOn == true){ + timer_sys.rds_reset_en = FM_RDS_RST_ENABLE; + } + ret = MT6620_RDS_OnOff(fm, cxt->rxcxt.rdsOn); + if(ret){ + FM_LOG_WAR(D_MAIN, "MT6620_RDS_OnOff failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + + //set audio path to I2S +#ifdef FM_DIGITAL_INPUT + mt_combo_audio_ctrl(COMBO_AUDIO_STATE_2); +#endif + break; + case FM_PWR_TX_ON: + fm_powerdown(fm, FM_TX); + parm.band = fm->band; + parm.freq = cxt->freq; + parm.space = FM_SPACE_100K; + ret = fm_powerup_tx(fm, &parm); + if(ret){ + FM_LOG_WAR(D_MAIN, "fm_powerup_tx failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + //set audio path to I2S +#ifdef FM_DIGITAL_OUTPUT + mt_combo_audio_ctrl(COMBO_AUDIO_STATE_2); +#endif + //RDS TX + ret = MT6620_Rds_Tx_Enable(1); + if(ret){ + FM_LOG_WAR(D_MAIN, "MT6620_Rds_Tx_Enable failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + ret = MT6620_Rds_Tx(cxt->txcxt.pi, cxt->txcxt.ps, cxt->txcxt.other_rds, cxt->txcxt.other_rds_cnt); + if(ret){ + FM_LOG_WAR(D_MAIN, "MT6620_Rds_Tx failed!\n"); + //FIX ME, how to handle this case? + goto out; + } + break; + case FM_PWR_OFF: + FM_LOG_WAR(D_MAIN, "fm was pwr down, no need powerup!\n"); + break; + default: + FM_LOG_ERR(D_MAIN, "error para!\n"); + break; + } + } +out: + FM_LOG_NTC(D_MAIN,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return ret; +} + +static void fm_rst_recover_worker_func(struct work_struct *work) +{ + int ret = 0; + + FM_LOG_NTC(D_MAIN,"+%s():\n", __func__); + + fm_cxt->ref = fm_cb->ref; + fm_cxt->freq = _current_frequency; + + //set all event flag false + spin_lock(&flag_lock); + flag = 0x0; + spin_unlock(&flag_lock); + ret = fm_recover_func(fm_cb, fm_cxt); + if(ret){ + FM_LOG_ERR(D_MAIN,"fm_recover_func failed\n"); + } + + chip_rst_state = FM_WHOLECHIP_RST_OFF; + FM_LOG_NTC(D_MAIN,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return; +} + +static void fm_subsys_recover_worker_func(struct work_struct *work) +{ + int ret = 0; + + FM_LOG_NTC(D_MAIN,"+%s():\n", __func__); + if(chip_rst_state != FM_WHOLECHIP_RST_OFF){ + FM_LOG_WAR(D_MAIN,"FM whole chip resetting\n"); + goto out; + } + fm_cxt->ref = fm_cb->ref; + fm_cxt->freq = _current_frequency; + //set all event flag false + spin_lock(&flag_lock); + flag = 0x0; + spin_unlock(&flag_lock); + ret = fm_recover_func(fm_cb, fm_cxt); + if(ret){ + FM_LOG_ERR(D_MAIN,"fm_recover_func failed\n"); + } + +out: + subsys_rst_state = FM_SUBSYS_RST_OFF; + FM_LOG_NTC(D_MAIN,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return; +} + +static void fm_rx_worker_func(struct work_struct *work) +{ + int len; + int i = 0; + static volatile fm_task_parser_state state = FM_TASK_RX_PARSER_PKT_TYPE; + uint8_t opcode = 0; + uint16_t length = 0; + unsigned char ch; + unsigned char rx_buf[RX_BUF_SIZE + 10] = {0}; //the 10 bytes are protect gaps + struct fm *fm = fm_cb; + RDSData_Struct *pstRDSData = fm->pstRDSData; + static int cnt2 = 0; + + FM_LOG_DBG(D_MAIN,"cnt2=%d\n", ++cnt2); + len = mtk_wcn_stp_receive_data(rx_buf, RX_BUF_SIZE, FM_TASK_INDX); + FM_LOG_DBG(D_RX,"+%s():[len=%d],[CMD=0x%02x 0x%02x 0x%02x 0x%02x]\n", __func__, len, rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3]); + + while (i < len){ + ch = rx_buf[i]; + + switch (state){ + case FM_TASK_RX_PARSER_PKT_TYPE: + if(ch == FM_TASK_EVENT_PKT_TYPE){ + if((i+5) < RX_BUF_SIZE){ + FM_LOG_DBG(D_RX,"0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x \n", rx_buf[i], rx_buf[i+1], rx_buf[i+2], rx_buf[i+3], rx_buf[i+4], rx_buf[i+5]); + }else{ + FM_LOG_DBG(D_RX,"0x%02x 0x%02x\n", rx_buf[i], rx_buf[i+1]); + } + state = FM_TASK_RX_PARSER_OPCODE; + }else{ + FM_LOG_ERR(D_RX,"%s(): event pkt type error (rx_buf[%d] = 0x%02x)\n", __func__, i, ch); + } + i++; + break; + + case FM_TASK_RX_PARSER_OPCODE: + i++; + opcode = ch; + state = FM_TASK_RX_PARSER_PKT_LEN_1; + break; + + case FM_TASK_RX_PARSER_PKT_LEN_1: + i++; + length = ch; + state = FM_TASK_RX_PARSER_PKT_LEN_2; + break; + + case FM_TASK_RX_PARSER_PKT_LEN_2: + i++; + length |= (uint16_t)(ch << 0x8); + if(length > 0){ + state = FM_TASK_RX_PARSER_PKT_PAYLOAD; + }else{ + spin_lock(&flag_lock); + flag |= (1 << opcode); + spin_unlock(&flag_lock); + state = FM_TASK_RX_PARSER_PKT_TYPE; + FM_LOG_DBG(D_RX,"[flag=0x%08x]\n", flag); + wake_up(&fm_wq); + } + break; + + case FM_TASK_RX_PARSER_PKT_PAYLOAD: + switch(opcode){ + case FM_SEEK_OPCODE: + spin_lock(&flag_lock); + flag |= FLAG_SEEK_DONE; + spin_unlock(&flag_lock); + if((i+1) < RX_BUF_SIZE){ + seek_result = (rx_buf[i] + (rx_buf[i+1] << 8)) / 10; + } + FM_LOG_DBG(D_RX,"[flag=0x%08x]\n", flag); + wake_up(&fm_wq); + break; + + case FM_SCAN_OPCODE: + spin_lock(&flag_lock); + flag |= FLAG_SCAN_DONE; + spin_unlock(&flag_lock); + //check if the result data is long enough + if((RX_BUF_SIZE - i) < (sizeof(uint16_t) * MT6620_SCANTBL_SIZE)){ + FM_LOG_ERR(D_RX,"FM_SCAN_OPCODE err, [tblsize=%d],[bufsize=%d]\n", (sizeof(uint16_t) * MT6620_SCANTBL_SIZE), (RX_BUF_SIZE - i)); + wake_up(&fm_wq); + return; + } + memcpy(scan_result, &rx_buf[i], sizeof(uint16_t) * MT6620_SCANTBL_SIZE); + FM_LOG_DBG(D_RX,"[flag=0x%08x]\n", flag); + wake_up(&fm_wq); + break; + + case FSPI_READ_OPCODE: + spin_lock(&flag_lock); + flag |= (1 << opcode); + spin_unlock(&flag_lock); + if((i+1) < RX_BUF_SIZE){ + fspi_rd = (rx_buf[i] + (rx_buf[i+1] << 8)); + } + FM_LOG_DBG(D_RX,"[flag=0x%08x]\n", flag); + wake_up(&fm_wq); + break; + + case RDS_RX_DATA_OPCODE: + spin_lock(&flag_lock); + flag |= (1 << opcode); + spin_unlock(&flag_lock); + FM_LOG_INF(D_RX,"-fm_rds_mutex\n"); + if (down_interruptible(&fm_rds_mutex)){ + FM_LOG_ERR(D_RX,"Handle RDS: down rds mutex failed\n"); + return; + } + rds_rx_size = length; + //check if the rds data is long enough + if((RX_BUF_SIZE - i) < rds_rx_size){ + FM_LOG_ERR(D_RX,"RDS_RX_DATA_OPCODE err, [rdsrxsize=%d],[bufsize=%d]\n", (int)rds_rx_size, (RX_BUF_SIZE - i)); + goto rds_out; + } + memcpy(&rds_rx_result, &rx_buf[i], rds_rx_size); + FM_LOG_DBG(D_RX,"[rds_rx_size=%d]\n", rds_rx_size); + #if 0 //RDS Rx verification + { + int grp; + int j = 4; + unsigned char *ptr = &rx_buf[i]; + + printk("%lu\t", jiffies * 1000 / HZ); + FM_LOG_NTC(D_RX,"%lu\t", jiffies * 1000 / HZ); + for(grp = 0; grp < 6; grp++, j+=12){ + FM_LOG_NTC(D_RX,"%02x%02x%02x%02x%02x%02x%02x%02x\t%02x%02x%02x%02x\t", ptr[j], ptr[j+1], ptr[j+2], ptr[j+3], ptr[j+4], ptr[j+5], ptr[j+6], ptr[j+7], ptr[j+8], ptr[j+9], ptr[j+10], ptr[j+11]); + } + FM_LOG_NTC(D_RX,"\n"); + } + #endif + + /*Handle the RDS data that we get*/ + MT6620_RDS_Eint_Handler(fm, &rds_rx_result, rds_rx_size); +rds_out: + up(&fm_rds_mutex); + FM_LOG_INF(D_RX,"+fm_rds_mutex\n"); + + //loop pstRDSData->event_status then act + //if(pstRDSData->event_status != 0) + if((pstRDSData->event_status != 0) && (pstRDSData->event_status + != RDS_EVENT_AF_LIST)){ + FM_LOG_DBG(D_RX,"Notify user to read, [event:%04x]\n", pstRDSData->event_status); + fm->RDS_Data_ready = true; + wake_up_interruptible(&fm->read_wait); + } + + FM_LOG_DBG(D_RX,"%s():[flag=0x%08x]\n", __func__, flag); + wake_up(&fm_wq); + break; + + default: + spin_lock(&flag_lock); + flag |= (1 << opcode); + spin_unlock(&flag_lock); + FM_LOG_DBG(D_RX,"[flag=0x%08x]\n", flag); + wake_up(&fm_wq); + break; + } + state = FM_TASK_RX_PARSER_PKT_TYPE; + i += length; + break; + + default: + break; + } + } + FM_LOG_DBG(D_RX,"-%s():\n", __func__); +} + +static int fm_setup_cdev(struct fm *fm) +{ + int err; + int alloc_ret = 0; + + /*static allocate chrdev*/ + fm->dev_t = MKDEV(FM_major, 0); + alloc_ret = register_chrdev_region(fm->dev_t, 1, FM_NAME); + if (alloc_ret){ + FM_LOG_ERR(D_ALL,"%s():fail to register chrdev\n", __func__); + return alloc_ret; + } +#if 0 + //dynamic allocate chrdev + err = alloc_chrdev_region(&fm->dev_t, 0, 1, FM_NAME); + if (err) { + FM_LOG_ERR(D_MAIN,"alloc dev_t failed\n"); + return -1; + } +#endif + FM_LOG_NTC(D_MAIN,"alloc %s:%d:%d\n", FM_NAME, MAJOR(fm->dev_t), MINOR(fm->dev_t)); + cdev_init(&fm->cdev, &fm_ops); + + fm->cdev.owner = THIS_MODULE; + fm->cdev.ops = &fm_ops; + + err = cdev_add(&fm->cdev, fm->dev_t, 1); + if (err){ + FM_LOG_ERR(D_ALL,"%s():alloc dev_t failed\n", __func__); + return -1; + } + + return 0; +} + +/* + * fm_ops_ioctl + * + * ioctl system call interface changed, in order to enhance system performance, + * Linux kernel 3.0 will not support ioctl(), so we shoud use unlocked_ioctl(). + * We should be care of race condition, and lock is a valid way to protect our data. + * + * @filp - current strcut file's pointer, we can get dentry and inode info by it + * @cmd - ioctl command that was send by ioctl caller + * @arg - usually it's the pointer of a data structure defined in user space + * + * If success, return 0; else error code + */ +static long fm_ops_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + struct fm *fm = container_of(filp->f_dentry->d_inode->i_cdev, struct fm, cdev); + + FM_LOG_INF(D_MAIN,"%s():\n", __func__); + + //check if we are resetting + if(chip_rst_state != FM_WHOLECHIP_RST_OFF){ + FM_LOG_WAR(D_MAIN, "whole chip is resetting, retry later\n"); + ret = -ERR_WHOLECHIP_RST; + //ret = 0; + return ret; + } + + if(subsys_rst_state != FM_SUBSYS_RST_OFF){ + FM_LOG_WAR(D_MAIN, "FM subsys is resetting, retry later\n"); + ret = -ERR_SUBSYS_RST; + //ret = 0; + return ret; + } + + switch(cmd){ + case FM_IOCTL_POWERUP:{ + struct fm_tune_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_POWERUP......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_powerup(fm, &parm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + + break; + } + + case FM_IOCTL_POWERDOWN:{ + int32_t type = -1; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_POWERDOWN......\n"); + FM_LOG_DBG(D_IOCTL,"[chipon=%d],[powerup=%d],[ref=%d]\n", + fm->chipon, + fm->powerup, + fm->ref); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip already is off\n"); + return -EFAULT; + } + if (copy_from_user(&type, (void*)arg, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_powerdown(fm, type); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + + // tune (frequency, auto Hi/Lo ON/OFF ) + case FM_IOCTL_TUNE:{ + struct fm_tune_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_TUNE......\n"); +// FIXME! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_tune(fm, &parm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_SEEK:{ + struct fm_seek_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_SEEK......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_seek_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_seek(fm, &parm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if (copy_to_user((void*)arg, &parm, sizeof(struct fm_seek_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_SCAN:{ + struct fm_scan_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_SCAN......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + if(copy_from_user(&parm, (void*)arg, sizeof(struct fm_scan_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_scan(fm, &parm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if(copy_to_user((void*)arg, &parm, sizeof(struct fm_scan_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + //XHC + //ret = 0; + break; + } + + case FM_IOCTL_SCAN_GETRSSI:{ + struct fm_rssi_req *req; + if(!(req = kzalloc(sizeof(struct fm_rssi_req), GFP_KERNEL))){ + FM_LOG_ERR(D_INIT,"kzalloc(fm) -ENOMEM\n"); + return -EFAULT; + } + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_SCAN_GETRSSI......\n"); + FM_COM_ASSERT(TRUE == fm->chipon); + if(copy_from_user(req, (void*)arg, sizeof(struct fm_rssi_req))){ + FM_LOG_ERR(D_IOCTL, "copy_from_user error\n"); + kfree(req); + return -EFAULT; + } + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL, "get fm_ops_mutex error\n"); + kfree(req); + return -EFAULT; + } + ret = fm_get_rssi_after_scan(fm, req); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL, "fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + if(copy_to_user((void*)arg, req, sizeof(struct fm_rssi_req))){ + FM_LOG_ERR(D_IOCTL, "copy_to_user error\n"); + kfree(req); + return -EFAULT; + } + kfree(req); + break; + } + + case FM_IOCTL_SETVOL:{ + uint32_t vol; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_SETVOL......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if(copy_from_user(&vol, (void*)arg, sizeof(uint32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_SETVOL, [vol=%d]\n", vol); + ret = fm_setvol(fm, vol); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + case FM_IOCTL_GETVOL:{ + uint32_t vol; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETVOL......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_getvol(fm, &vol); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &vol, sizeof(uint32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_IS_FM_POWERED_UP:{ + uint32_t pwredup = 0; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_IS_FM_POWERED_UP......\n"); + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + pwredup = fm->powerup; + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_IS_FM_POWERED_UP,[powerup=%d]\n", pwredup); + if (copy_to_user((void*)arg, &pwredup, sizeof(uint32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_MUTE:{ + uint32_t bmute; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_MUTE......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (copy_from_user(&bmute, (void*)arg, sizeof(uint32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_MUTE:[mute=%d]\n", bmute); + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + if (bmute){ + ret = MT6620_Mute(true); + }else{ + ret = MT6620_Mute(false); + } + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + + case FM_IOCTL_GETRSSI:{ + int rssi = 0; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETRSSI......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_getrssi(fm, &rssi); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &rssi, sizeof(int))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_RW_REG:{ + struct fm_ctl_parm parm_ctl; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RW_REG......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if (copy_from_user(&parm_ctl, (void*)arg, sizeof(struct fm_ctl_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + //write + if(parm_ctl.rw_flag == 0){ + FM_LOG_DBG(D_IOCTL,"Write Reg %02x:%04x\n", parm_ctl.addr, parm_ctl.val); + ret = MT6620_write(parm_ctl.addr, parm_ctl.val); + }else{ + ret = MT6620_read(parm_ctl.addr, &parm_ctl.val); + FM_LOG_DBG(D_IOCTL,"Read Reg %02x:%04x, [ret=%d]\n", parm_ctl.addr, parm_ctl.val, ret); + } + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + // Read success. + if ((parm_ctl.rw_flag == 0x01) && (!ret)){ + if (copy_to_user((void*)arg, &parm_ctl, sizeof(struct fm_ctl_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + } + break; + } + + case FM_IOCTL_GETCHIPID:{ + uint16_t chipid; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETCHIPID......\n"); + + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + //ret = MT6620_read(0x62, &chipid); + chipid = fm->chip_id; + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_GETCHIPID:%04x\n", chipid); + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if (copy_to_user((void*)arg, &chipid, sizeof(uint16_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + + break; + } + + case FM_IOCTL_GETMONOSTERO:{ + uint16_t usStereoMono; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETMONOSTERO......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + ret = MT6620_GetMonoStereo(&usStereoMono); + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_GETMONOSTERO:%04x\n", usStereoMono); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if (copy_to_user((void*)arg, &usStereoMono, sizeof(uint16_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + + break; + } + + case FM_IOCTL_SETMONOSTERO:{ + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_SETMONOSTERO......\n"); + FM_COM_ASSERT(TRUE == fm->chipon); + ret = MT6620_SetMonoStereo((int)arg); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + break; + } + + case FM_IOCTL_GETCURPAMD:{ + uint16_t PamdLevl; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETCURPAMD......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + ret = MT6620_GetCurPamd(&PamdLevl); + FM_LOG_DBG(D_MAIN,"FM_IOCTL_GETCURPAMD:%d\n", PamdLevl); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if (copy_to_user((void*)arg, &PamdLevl, sizeof(uint16_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + + break; + } + + case FM_IOCTL_EM_TEST:{ + struct fm_em_parm parm_em; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_EM_TEST......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if (copy_from_user(&parm_em, (void*)arg, sizeof(struct fm_em_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + ret = MT6620_em_test(parm_em.group_idx, parm_em.item_idx, parm_em.item_value); + + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + break; + } + + case FM_IOCTL_RDS_SUPPORT:{ + int support; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RDS_SUPPORT......\n"); + + support = FM_RDS_ENABLE; + if (copy_to_user((void*)arg, &support, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_RDS_ONOFF:{ + uint16_t rds_onoff = 0;; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RDS_ONOFF......\n"); + FM_LOG_DBG(D_IOCTL,"[chipon=%d] [powerup=%d] [ref=%d]\n", + fm->chipon, + fm->powerup, + fm->ref); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if (copy_from_user(&rds_onoff, (void*)arg, sizeof(uint16_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + if(rds_onoff){ + if((ret = MT6620_RDS_OnOff(fm, true))){ + FM_LOG_ERR(D_IOCTL,"FM_IOCTL_RDS_ONOFF faield\n"); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + return -EPERM; + } + //fm_enable_eint(); + fm_enable_rds_BlerCheck(fm); + fm_cxt->rxcxt.rdsOn = true; + FM_LOG_DBG(D_MAIN,"FM_IOCTL_RDS_ON:%d\n", jiffies_to_msecs(jiffies)); + }else{ + //fm_disable_eint(); + fm->RDS_Data_ready = true; + memset(fm->pstRDSData, 0, sizeof(RDSData_Struct)); + wake_up_interruptible(&fm->read_wait); + fm_disable_rds_BlerCheck(); + ret = MT6620_RDS_OnOff(fm, false); + fm_cxt->rxcxt.rdsOn = false; + FM_LOG_DBG(D_MAIN,"FM_IOCTL_RDS_OFF:%d\n", jiffies_to_msecs(jiffies)); + } + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + + case FM_IOCTL_GETGOODBCNT:{ + uint16_t uGBLCNT = 0; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETGOODBCNT......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + FM_LOG_INF(D_IOCTL,"-fm_read_mutex\n"); + if (down_interruptible(&fm_read_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + uGBLCNT = GOOD_BLK_CNT; + up(&fm_read_mutex); + FM_LOG_INF(D_IOCTL,"+fm_read_mutex\n"); + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_GETGOODBCNT:%d\n", uGBLCNT); + if (copy_to_user((void*)arg, &uGBLCNT, sizeof(uint16_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + case FM_IOCTL_GETBADBNT:{ + uint16_t uBadBLCNT = 0; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETBADBNT......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + FM_LOG_INF(D_IOCTL,"-fm_read_mutex\n"); + if (down_interruptible(&fm_read_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + uBadBLCNT = BAD_BLK_CNT; + up(&fm_read_mutex); + FM_LOG_INF(D_IOCTL,"+fm_read_mutex\n"); + + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_GETBADBNT:%d\n", uBadBLCNT); + if (copy_to_user((void*)arg, &uBadBLCNT, sizeof(uint16_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_GETBLERRATIO:{ + uint16_t uBlerRatio = 0; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETBLERRATIO......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_read_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + uBlerRatio = (uint16_t)BAD_BLK_RATIO; + up(&fm_read_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_GETBLERRATIO:%d\n", uBlerRatio); + if (copy_to_user((void*)arg, &uBlerRatio, sizeof(uint16_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + #ifdef FMDEBUG + case FM_IOCTL_DUMP_REG:{ + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_DUMP_REG......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = MT6620_dump_reg(); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + #endif + + case FM_IOCTL_POWERUP_TX:{ + struct fm_tune_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_POWERUP_TX......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_powerup_tx(fm, &parm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + // tune (frequency, auto Hi/Lo ON/OFF ) + case FM_IOCTL_TUNE_TX:{ + struct fm_tune_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_TUNE_TX......\n"); +// FIXME! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_tune_tx(fm, &parm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tune_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_TX_SUPPORT:{ + int32_t tx_support = -1; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_TX_SUPPORT......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + if(FM_TX_SUPPORT == atomic_read(&fm->tx_support)){ + tx_support = 1; + }else if(FM_TX_NOT_SUPPORT == atomic_read(&fm->tx_support)){ + tx_support = 0; + }else{ + tx_support = -1; + FM_LOG_ERR(D_IOCTL,"FM_IOCTL_TX_SUPPORT:invalid flag[fm->tx_support=%d]\n", + atomic_read(&fm->tx_support)); + ret = -1; + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &tx_support, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_RDSTX_ENABLE:{ + int32_t rds_tx_enable = -1; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RDSTX_ENABLE......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + if(copy_from_user(&rds_tx_enable, (void*)arg, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + if(FM_RDS_TX_ENABLE == rds_tx_enable){ + atomic_set(&fm->rds_tx_enable, FM_RDS_TX_ENABLE); + }else if(FM_RDS_TX_DISENABLE == rds_tx_enable){ + atomic_set(&fm->rds_tx_enable, FM_RDS_TX_DISENABLE); + }else{ + FM_LOG_ERR(D_IOCTL,"FM_IOCTL_RDSTX_ENABLE:invalid para[rds_tx_enable=%d]\n", + rds_tx_enable); + ret = -1; + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + + case FM_IOCTL_RDSTX_SUPPORT:{ + int32_t rds_tx_support = -1; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RDSTX_SUPPORT......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + if(FM_RDS_TX_SUPPORT == atomic_read(&fm->rds_tx_support)){ + rds_tx_support = 1; + }else if(FM_RDS_TX_NOT_SUPPORT == atomic_read(&fm->rds_tx_support)){ + rds_tx_support = 0; + }else{ + rds_tx_support = -1; + FM_LOG_ERR(D_IOCTL,"FM_IOCTL_RDSTX_SUPPORT:invalid flag[fm->rds_tx_support=%d]\n", + atomic_read(&fm->rds_tx_support)); + ret = -1; + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &rds_tx_support, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_TX_SCAN:{ + struct fm_tx_scan_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_TX_SCAN......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_tx_scan_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + ret = fm_tx_scan(fm, &parm); + if(ret < 0){ + FM_LOG_ERR(D_MAIN,"FM_IOCTL_TX_SCAN failed\n"); + } + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &parm, sizeof(struct fm_tx_scan_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + case FM_IOCTL_RDS_TX:{ + struct fm_rds_tx_parm parm; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RDS_TX......\n"); +// FIXME!! +// if (!capable(CAP_SYS_ADMIN)) +// return -EPERM; + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + + if (copy_from_user(&parm, (void*)arg, sizeof(struct fm_rds_tx_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_rds_tx(fm, &parm); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &parm, sizeof(struct fm_rds_tx_parm))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_OVER_BT_ENABLE:{ + int32_t fm_via_bt = -1; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_OVER_BT_ENABLE......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + if(copy_from_user(&fm_via_bt, (void*)arg, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + ret = fm_over_bt(fm, fm_via_bt); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + if(FM_OVER_BT_ENABLE == fm_via_bt){ + atomic_set(&fm->over_bt_enable, FM_OVER_BT_ENABLE); + }else if(FM_OVER_BT_DISABLE == fm_via_bt){ + atomic_set(&fm->over_bt_enable, FM_OVER_BT_DISABLE); + }else{ + FM_LOG_ERR(D_IOCTL,"FM_IOCTL_OVER_BT_ENABLE:invalid para[fm_over_bt=%d]\n", + fm_via_bt); + ret = -1; + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + + case FM_IOCTL_ANA_SWITCH:{ + int32_t antenna = -1; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_ANA_SWITCH......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + if(copy_from_user(&antenna, (void*)arg, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + ret = fm_antenna_switch(fm, antenna); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + break; + } + + case FM_IOCTL_GETCAPARRAY:{ + int caparray; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GETCAPARRAY......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + ret = MT6620_GetCapArray(&caparray); + FM_LOG_DBG(D_IOCTL,"FM_IOCTL_GETMONOSTERO:%x\n", caparray); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fw no response, do hw reset\n"); + fm_hw_reset(); + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + + if (copy_to_user((void*)arg, &caparray, sizeof(int32_t))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_GPS_RTC_DRIFT:{ + struct fm_gps_rtc_info rtc_info; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GPS_RTC_DRIFT......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + if(copy_from_user(&rtc_info, (void*)arg, sizeof(struct fm_gps_rtc_info))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + + ret = fm_get_gps_rtc_info(&gps_rtc_info, &rtc_info); + if(ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"fm_get_gps_rtc_info error\n"); + return ret; + } + break; + } + + case FM_IOCTL_I2S_SETTING:{ + struct fm_i2s_setting i2s_cfg; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_I2S_SETTING......\n"); + + if (FALSE == fm->chipon){ + FM_LOG_ERR(D_IOCTL,"ERROR, FM chip is OFF\n"); + return -EFAULT; + } + if(copy_from_user(&i2s_cfg, (void*)arg, sizeof(struct fm_i2s_setting))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + + ret = MT6620_I2S_Setting(i2s_cfg.onoff, i2s_cfg.mode, i2s_cfg.sample); + if(ret){ + FM_LOG_ERR(D_IOCTL|D_ALL,"MT6620_I2S_Setting error\n"); + return ret; + } + break; + } + case FM_IOCTL_RDS_GROUPCNT:{ + struct rds_group_cnt_req gc_req; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RDS_GROUPCNT......\n"); + if (copy_from_user(&gc_req, (void*)arg, sizeof(struct rds_group_cnt_req))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_from_user error\n"); + return -EFAULT; + } + FM_LOG_INF(D_IOCTL,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + //handle group counter request + switch(gc_req.op){ + case RDS_GROUP_CNT_READ: + rds_group_counter_get(&gc_req.gc, &fm->rds_gc); + break; + case RDS_GROUP_CNT_WRITE: + break; + case RDS_GROUP_CNT_RESET: + rds_group_counter_reset(&fm->rds_gc); + break; + default: + break; + } + up(&fm_ops_mutex); + FM_LOG_INF(D_IOCTL,"+fm_ops_mutex\n"); + if (copy_to_user((void*)arg, &gc_req, sizeof(struct rds_group_cnt_req))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + case FM_IOCTL_RDS_GET_LOG:{ + struct rds_raw_data rds_log; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_RDS_GET_LOG......\n"); + rds_log.dirty = TRUE; + rds_log.len = rds_rx_size; + memcpy(&rds_log.data[0], (const void*)&rds_rx_result, sizeof(struct rds_rx)); + if (copy_to_user((void*)arg, &rds_log, sizeof(struct rds_raw_data))){ + FM_LOG_ERR(D_IOCTL|D_ALL,"copy_to_user error\n"); + return -EFAULT; + } + break; + } + + case FM_IOCTL_GET_HW_INFO:{ + struct fm_hw_info info; + FM_LOG_DBG(D_IOCTL,"......FM_IOCTL_GET_HW_INFO......\n"); + FM_COM_ASSERT(TRUE == fm->chipon); + + if(down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL, "get hw info, get fm_ops_mutex error\n"); + return -EFAULT; + } + ret = fm_get_hw_info(fm, &info); + if(-ERR_FW_NORES == ret){ + FM_LOG_ERR(D_IOCTL, "get hw info, fw no response, do hw reset\n"); + fm_hw_reset(); + } + up(&fm_ops_mutex); + if(copy_to_user((void*)arg, &info, sizeof(struct fm_hw_info))){ + FM_LOG_ERR(D_IOCTL, "get hw info, copy_to_user error\n"); + return -EFAULT; + } + break; + } + + default: + FM_LOG_ERR(D_IOCTL,"Invalid IOCTL[cmd=%d], please check!\n", cmd); + return -EPERM; + } + return ret; +} + +static loff_t fm_ops_lseek(struct file *filp, loff_t off, int whence) +{ + if(whence == SEEK_END){ + MT6620_ScanForceStop(); + } + return off; +} + +static ssize_t fm_ops_read(struct file *filp, char *buf, size_t len, loff_t *off) +{ + struct fm *fm = filp->private_data; + int copy_len = 0, left = 0; + uint8_t indx; + + indx = 0; + FM_LOG_DBG(D_MAIN,"+%s():\n", __func__); + if (!fm){ + FM_LOG_ERR(D_MAIN,"%s():invalid fm pointer\n", __func__); + return 0; + } + + if(!buf || len < sizeof(RDSData_Struct)){ + FM_LOG_ERR(D_ALL,"%s():invalid buf\n", __func__); + return 0; + } + copy_len = sizeof(RDSData_Struct); + +RESTART: + if((fm->RDS_Data_ready == true) || (fm->powerup == FM_PWR_OFF)){ + + //block when FM is resetting + while((chip_rst_state != FM_WHOLECHIP_RST_OFF) || (subsys_rst_state != FM_SUBSYS_RST_OFF)){ + msleep_interruptible(100); + } + + FM_LOG_INF(D_MAIN,"-fm_rds_mutex\n"); + if (down_interruptible(&fm_rds_mutex)){ + FM_LOG_ERR(D_MAIN,"get fm_rds_mutex error\n"); + return 0; + } + + if(fm->powerup == FM_PWR_OFF){ + memset(fm->pstRDSData, 0, sizeof(RDSData_Struct)); + } + + if((left = copy_to_user((void *)buf, fm->pstRDSData, (unsigned long)copy_len))){ + FM_LOG_ERR(D_MAIN,"%s():copy_to_user failed\n", __func__); + } + FM_LOG_DBG(D_MAIN,"copy len=%d\n", (copy_len-left)); + //Clear + if(left == 0){ + fm->pstRDSData->event_status = 0x0; + } + fm->RDS_Data_ready = false; + up(&fm_rds_mutex); + FM_LOG_INF(D_MAIN,"+fm_rds_mutex\n"); + }else{ + FM_LOG_DBG(D_MAIN,"wait event\n"); + if (wait_event_interruptible(fm->read_wait, (fm->RDS_Data_ready == true)) == 0){ + FM_LOG_DBG(D_MAIN,"wait event success[%d]\n", fm->RDS_Data_ready); + goto RESTART; + }else { + FM_LOG_ERR(D_MAIN,"%s():wait event err[%d]\n", __func__, fm->RDS_Data_ready); + fm->RDS_Data_ready = false; + return 0; + } + } + + FM_LOG_DBG(D_MAIN,"-%s():\n", __func__); + return (copy_len-left); +} + +static int fm_ops_open(struct inode *inode, struct file *filp) +{ + int ret = 0; + struct fm *fm = container_of(inode->i_cdev, struct fm, cdev); + + fm_get_process_path(fm); + + FM_LOG_DBG(D_MAIN,"+%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + + //check if we are resetting + if(chip_rst_state != FM_WHOLECHIP_RST_OFF){ + FM_LOG_WAR(D_MAIN, "FM is resetting, please open later\n"); + ret = -ERR_WHOLECHIP_RST; + return ret; + } + + if(subsys_rst_state != FM_SUBSYS_RST_OFF){ + FM_LOG_WAR(D_MAIN, "FM subsys is resetting, retry later\n"); + ret = -ERR_SUBSYS_RST; + return ret; + } + + FM_LOG_INF(D_MAIN,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_IOCTL|D_ALL,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + fm->ref++; + FM_LOG_NTC(D_MAIN,"%s [fm->ref=%d]\n", __func__, fm->ref); + //Audio driver will open first handle, for save power. + if(fm->ref > 0){ + if(FALSE == fm->chipon){ + //Turn on FM on 6620 chip by WMT driver + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM)) { + FM_LOG_ERR(D_MAIN,"%s WMT turn on FM fail!\n", __func__); + ret = -ENODEV; + goto out; + } + fm->chipon = true; + fm_cxt->chipon = true; + spin_lock(&flag_lock); + flag = 0; //FM info flag + spin_unlock(&flag_lock); + /* GeorgeKuo: turn on function before check stp ready */ + if(FALSE == mtk_wcn_stp_is_ready()){ + fm->chipon = false; + fm_cxt->chipon = false; + fm->ref--; + FM_LOG_ERR(D_MAIN,"6620 stp is not ready, please retry later\n"); + ret = -ENODEV; + goto out; + } + //Register the main Callback func that will get data form 6620 FM firware + mtk_wcn_stp_register_event_cb(FM_TASK_INDX, stp_rx_event_cb); + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_FM, fm_wholechip_rst_cb); + FM_LOG_NTC(D_MAIN,"%s WMT turn on FM OK, [fm->chipon=%d]!\n", __func__, fm->chipon); + } + } + +out: + up(&fm_ops_mutex); + FM_LOG_INF(D_MAIN,"+fm_ops_mutex\n"); + filp->private_data = fm; + FM_LOG_DBG(D_MAIN,"-%s():[T=%d]\n", __func__, jiffies_to_msecs(jiffies)); + return ret; +} + +static int fm_ops_release(struct inode *inode, struct file *filp) +{ + int ret = 0; + struct fm *fm = container_of(inode->i_cdev, struct fm, cdev); + + FM_LOG_DBG(D_MAIN,"+%s()\n", __func__); + FM_LOG_INF(D_MAIN,"-fm_ops_mutex\n"); + if (down_interruptible(&fm_ops_mutex)){ + FM_LOG_ERR(D_MAIN,"get fm_ops_mutex error\n"); + return -EFAULT; + } + + if(fm->ref > 0){ + fm->ref--; + }else{ + FM_LOG_ERR(D_MAIN,"%s():open and close FM unmatch\n", __func__); + ret = -EFAULT; + } + FM_LOG_NTC(D_MAIN,"%s [fm->ref=%d]\n", __func__, fm->ref); + + //check if we are resetting + if(chip_rst_state != FM_WHOLECHIP_RST_OFF){ + FM_LOG_WAR(D_MAIN, "FM is resetting, only ref--\n"); + ret = -ERR_WHOLECHIP_RST; + up(&fm_ops_mutex); + FM_LOG_INF(D_MAIN,"+fm_ops_mutex\n"); + return ret; + } + + if(subsys_rst_state != FM_SUBSYS_RST_OFF){ + FM_LOG_WAR(D_MAIN, "FM subsys is resetting, only ref--\n"); + ret = -ERR_SUBSYS_RST; + up(&fm_ops_mutex); + FM_LOG_INF(D_MAIN,"+fm_ops_mutex\n"); + return ret; + } + if(fm->ref < 1){ + + fm_disable_rds_BlerCheck(); + ret = MT6620_RDS_OnOff(fm, FALSE); + + if(FM_PWR_RX_ON == fm->powerup){ + ret = fm_powerdown(fm, FM_RX); + }else if(FM_PWR_TX_ON == fm->powerup){ + ret = fm_powerdown(fm, FM_TX); + } + + if (TRUE == fm->chipon){ + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_FM)){ + FM_LOG_ERR(D_MAIN,"WMT turn off FM fail!\n"); + ret = -EFAULT; + }else{ + FM_LOG_NTC(D_MAIN,"WMT turn off FM OK!\n"); + } + fm->chipon = FALSE; + fm_cxt->chipon = false; + //Unregister FM main Callback + mtk_wcn_stp_register_event_cb(FM_TASK_INDX, NULL); + mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_FM); + } + } + + up(&fm_ops_mutex); + FM_LOG_INF(D_MAIN,"+fm_ops_mutex\n"); + FM_LOG_DBG(D_MAIN,"-%s()[ret=%d]\n", __func__, ret); + return ret; +} + +static int fm_get_process_path(struct fm *fm) +{ + int ret = 0; + +#ifdef FM_TASK_INFO_DEBUG + struct dentry *dnty = NULL; + FM_LOG_NTC(D_MAIN,"[TaskName=%s],[TaskId=%d]\n", current->comm, current->pid); + dnty = current->mm->mmap->vm_file->f_path.dentry; + printk("[%s]", dnty->d_name.name); + while(strcmp(dnty->d_name.name, "/")){ + dnty = dnty->d_parent; + printk("[%s]", dnty->d_name.name); + } + printk("\n"); +#endif + + return ret; +} + +static int fm_timer_init(struct fm *fm, struct fm_timer_sys *fmtimer, struct timer_list *timer) +{ + int ret = 0; + + fmtimer->onoff = FM_TIMER_SYS_OFF; + fmtimer->count = 0; + fmtimer->rds_reset_en = FM_RDS_RST_DISABLE; + fmtimer->tx_pwr_ctrl_en = FM_TX_PWR_CTRL_DISABLE; + fmtimer->tx_rtc_ctrl_en = FM_TX_RTC_CTRL_DISABLE; + fmtimer->tx_desense_en = FM_TX_DESENSE_DISABLE; + + init_timer(timer); + timer->expires = jiffies + FM_TIMER_TIMEOUT_MIN/(1000/HZ); + timer->function = fm_timer_func; + timer->data = (unsigned long)fm; + add_timer(timer); + + return ret; +} +static int fm_rtc_compensation_init(struct fm *fm, struct fm_gps_rtc_info *rtc) +{ + int ret = 0; + + rtc->err = 0; + rtc->age = 0; + rtc->drift = 0; + rtc->tv.tv_sec = 0; + rtc->tv.tv_usec = 0; + rtc->ageThd = FM_GPS_RTC_AGE_TH; + rtc->driftThd = FM_GPS_RTC_DRIFT_TH; + rtc->tvThd.tv_sec = FM_GPS_RTC_TIME_DIFF_TH; + rtc->retryCnt = FM_GPS_RTC_RETRY_CNT; + rtc->flag = FM_GPS_RTC_INFO_OLD; + + return ret; +} + +static int fm_print_cfg_info(struct fm *fm, void* data) +{ + int ret = 0; + + FM_LOG_NTC(D_INIT,"******fm config info******\n"); + FM_LOG_NTC(D_INIT,"***chip:\tMT6620\t\n"); + FM_LOG_NTC(D_INIT,"***band:\t%d\t\n", FMR_BAND); + FM_LOG_NTC(D_INIT,"***freq_min:\t%d\t\n", FMR_BAND_FREQ_L); + FM_LOG_NTC(D_INIT,"***freq_max:\t%d\t\n", FMR_BAND_FREQ_H); + FM_LOG_NTC(D_INIT,"***scan_tbl:\t%d\t\n", FMR_SCAN_CH_SIZE); + FM_LOG_NTC(D_INIT,"***space:\t%d\t\n", FMR_SEEK_SPACE); + FM_LOG_NTC(D_INIT,"***rssi_long:\t0x%04x\t\n", FMR_RSSI_TH_LONG); + FM_LOG_NTC(D_INIT,"***rssi_short:\t0x%04x\t\n", FMR_RSSI_TH_SHORT); + FM_LOG_NTC(D_INIT,"***CQI:\t0x%04x\t\n", FMR_CQI_TH); + FM_LOG_NTC(D_INIT,"******fm config end******\n"); + + return ret; +} + +static int fm_init() +{ + int err; + struct fm *fm = NULL; + + if (!(fm = kzalloc(sizeof(struct fm), GFP_KERNEL))){ + FM_LOG_ERR(D_INIT,"kzalloc(fm) -ENOMEM\n"); + err = -ENOMEM; + goto fm_alloc_err; + } + + if (!(tx_buf = kzalloc(TX_BUF_SIZE + 1, GFP_KERNEL))){ + FM_LOG_ERR(D_INIT,"kzalloc(tx_buf) -ENOMEM\n"); + err = -ENOMEM; + goto tx_alloc_err; + } + + if (!(fm_cxt = kzalloc(sizeof(struct fm_context), GFP_KERNEL))){ + FM_LOG_ERR(D_INIT,"kzalloc(fm_cxt) -ENOMEM\n"); + err = -ENOMEM; + goto tx_alloc_err; + } + + fm->ref = 0; + atomic_set(&fm->tx_support, FM_TX_SUPPORT); + atomic_set(&fm->rds_tx_support, FM_RDS_TX_SUPPORT); + atomic_set(&fm->rds_tx_enable, FM_RDS_TX_ENABLE); + atomic_set(&fm->over_bt_enable, FM_OVER_BT_DISABLE); + fm->chipon = false; + fm->powerup = FM_PWR_OFF; + fm->chip_id = 0x6620; + fm->tx_pwr = FMTX_PWR_LEVEL_MAX; + + if ((err = fm_setup_cdev(fm))){ + FM_LOG_ERR(D_INIT,"fm_setup_cdev() failed\n"); + goto setup_cdev_err; + } + + init_waitqueue_head(&fm->read_wait); + if (!(fm->pstRDSData = kmalloc(sizeof(RDSData_Struct), GFP_KERNEL))){ + FM_LOG_ERR(D_INIT,"-ENOMEM for RDS\n"); + err = -ENOMEM; + goto alloc_rds_err; + } + + fm->fm_workqueue = create_singlethread_workqueue("fm_workqueue"); + if(!fm->fm_workqueue){ + FM_LOG_ERR(D_INIT,"-ENOMEM for fm_workqueue\n"); + err = -ENOMEM; + goto rx_wq_err; + } + + + fm->fm_timer_workqueue = create_singlethread_workqueue("fm_timer_workqueue"); + if(!fm->fm_timer_workqueue){ + FM_LOG_ERR(D_INIT,"-ENOMEM for fm_timer_workqueue\n"); + err = -ENOMEM; + goto rds_reset_wq_err; + } + + + INIT_WORK(&fm->fm_rx_work, fm_rx_worker_func); + INIT_WORK(&fm->fm_rds_reset_work, fm_rds_reset_worker_func); + INIT_WORK(&fm->fm_tx_power_ctrl_work, fm_tx_power_ctrl_worker_func); + INIT_WORK(&fm->fm_tx_rtc_ctrl_work, fm_tx_rtc_ctrl_worker_func); + INIT_WORK(&fm->fm_tx_desense_wifi_work, fm_tx_desense_wifi_worker_func); + INIT_WORK(&fm->fm_rst_recover_work, fm_rst_recover_worker_func); + INIT_WORK(&fm->fm_subsys_recover_work, fm_subsys_recover_worker_func); + + fm_cb = fm; + + fm_rtc_compensation_init(fm_cb, &gps_rtc_info); + fm_timer_init(fm_cb, &timer_sys, &fm_timer); + + /*Add porc file system*/ + g_fm_proc = create_proc_entry(FM_PROC_FILE, 0666, NULL); + if (g_fm_proc == NULL){ + FM_LOG_ERR(D_INIT,"create_proc_entry failed\n"); + err = -ENOMEM; + goto rds_reset_wq_err; + }else{ + g_fm_proc->read_proc = fm_proc_read; + g_fm_proc->write_proc = fm_proc_write; + FM_LOG_NTC(D_INIT,"create_proc_entry success\n"); + } + + /*Add fm config porc file*/ + g_fm_config.proc = create_proc_entry(FM_PROC_CONFIG, 0666, NULL); + if (g_fm_config.proc == NULL){ + FM_LOG_ERR(D_INIT,"create_config_entry failed\n"); + err = -ENOMEM; + goto rds_reset_wq_err; + }else{ + g_fm_config.proc->read_proc = fmconfig_proc_read; + g_fm_config.proc->write_proc = fmconfig_proc_write; + FM_LOG_NTC(D_INIT,"create_config_entry success\n"); + } + + g_fm_config.vcooff = FM_TX_VCO_OFF_DEFAULT; //TX RTC VCO tracking interval(s) + g_fm_config.vcoon = FM_TX_VCO_ON_DEFAULT; //TX VCO tracking ON duiration(ms) + g_fm_config.rdsrst = FM_RDS_RST_INVAL_DEFAULT; //RDS RX Good/Bad block reset interval(s) + g_fm_config.txpwrctl = FM_TX_PWR_CTRL_INVAL_DEFAULT; //TX power contrl interval(s) + g_fm_config.timer = FM_TIMER_TIMEOUT_DEFAULT; //FM timer system time out interval(ms) + + err = fm_print_cfg_info(fm, NULL); + if(err){ + FM_LOG_ERR(D_INIT,"print fm cfg info failed\n"); + } + return 0; + +rds_reset_wq_err: + destroy_workqueue(fm->fm_workqueue); + +rx_wq_err: + kfree(fm->pstRDSData); + +alloc_rds_err: + cdev_del(&fm->cdev); + +setup_cdev_err: + kfree(tx_buf); + +tx_alloc_err: + kfree(fm); + +fm_alloc_err: + return err; +} + +static int fm_destroy(struct fm *fm) +{ + int err = 0; + + FM_LOG_NTC(D_INIT, "%s\n", __func__); + remove_proc_entry(FM_PROC_CONFIG, NULL); + remove_proc_entry(FM_PROC_FILE, NULL); + + if(NULL == fm){ + FM_LOG_ERR(D_INIT,"%s Invalid pointer fm\n", __func__); + err = -1; + } + del_timer(&fm_timer); + cdev_del(&fm->cdev); + unregister_chrdev_region(fm->dev_t, 1); + + flush_scheduled_work(); + + // FIXME: any other hardware configuration ? + + if(fm->fm_timer_workqueue){ + destroy_workqueue(fm->fm_timer_workqueue); + } + + if(fm->fm_workqueue){ + destroy_workqueue(fm->fm_workqueue); + } + + if (fm->pstRDSData){ + kfree(fm->pstRDSData); + fm->pstRDSData = NULL; + } + + // free all memory + if(fm_cxt){ + kfree(fm_cxt); + fm_cxt = NULL; + } + + if(tx_buf){ + kfree(tx_buf); + tx_buf = NULL; + } + + if(fm){ + kfree(fm); + } + fm_cb = NULL; + return err; +} + +static int do_cmd_send(struct fm *fm, unsigned char *buf, int len, int opcode, void* data){ + int ret = 0; + int pkt_size = 0; + + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_MAIN,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + return ret; + } + + //special defined cmd + if(buf && (len > 4) && (len < TX_BUF_SIZE)){ + FM_LOG_NTC(D_MAIN,"sending special cmd[len=%d]\n", len); + ret = fm_send_wait_timeout(buf, (uint16_t)len, + FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT); + if(ret){ + FM_LOG_ERR(D_MAIN,"send special cmd failed\n"); + goto out; + } + } + + //additional cmd for normal case + if(tx_buf == NULL){ + FM_LOG_ERR(D_MAIN,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + pkt_size = mt6620_com(tx_buf, TX_BUF_SIZE, opcode, NULL); + if(pkt_size < 0){ + FM_LOG_ERR(D_MAIN,"unsupported cmd\n"); + goto out; + } + FM_LOG_NTC(D_MAIN,"sending additional cmd[len=%d]\n", pkt_size); + ret = fm_send_wait_timeout(tx_buf, (uint16_t)pkt_size, + FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT); + if(ret){ + FM_LOG_ERR(D_MAIN,"send additional cmd failed\n"); + } + +out: + up(&fm_cmd_mutex); + return ret; +} + +/* + * fm_powerup + */ +static int fm_powerup(struct fm *fm, struct fm_tune_parm *parm) +{ + int ret = 0; + uint16_t pkt_size = 0; + + if(FM_PWR_RX_ON == fm->powerup){ + //FM RX already on + FM_LOG_NTC(D_MAIN,"%s, FM Rx already powered up\n", __func__); + parm->err = FM_BADSTATUS; + return 0; + }else if(FM_PWR_TX_ON == fm->powerup){ + //if Tx is on, we need pwr down TX first + ret = fm_powerdown(fm, FM_TX); + if(ret){ + FM_LOG_ERR(D_MAIN,"FM pwr down Tx fail!\n"); + return ret; + } + } + + //We should make chip on first before do Power on + if (FALSE == fm->chipon){ + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM)){ + FM_LOG_ERR(D_MAIN,"WMT turn on FM fail!\n"); + return -ENODEV; + } + FM_LOG_NTC(D_MAIN,"WMT turn on FM OK!\n"); + fm->chipon = TRUE; + } + + FM_LOG_INF(D_MAIN,"+MT6620 power on procedure\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_MAIN,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + return ret; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_MAIN,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto release_mutex; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_off_2_longANA(tx_buf, TX_BUF_SIZE); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT); + if(ret){ + FM_LOG_ERR(D_MAIN,"%s(): mt6620_off_2_longANA failed\n", __func__); + goto release_mutex; + } + + pkt_size = mt6620_rx_digital_init(tx_buf, TX_BUF_SIZE); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT); + if(ret){ + FM_LOG_ERR(D_MAIN,"%s(): mt6620_rx_digital_init failed\n", __func__); + goto release_mutex; + } + +release_mutex: + up(&fm_cmd_mutex); + + if(ret) + return ret; + +#ifdef FM_DIGITAL_INPUT + #ifdef MT6573 //for MT6573 + if(get_chip_eco_ver() == CHIP_E1){ + ret = MT6620_I2S_Setting(FM_I2S_ON, FM_I2S_MASTER, FM_I2S_48K); + }else{ + ret = MT6620_I2S_Setting(FM_I2S_ON, FM_I2S_SLAVE, FM_I2S_48K); + } + #else //for MT6575 + ret = MT6620_I2S_Setting(FM_I2S_ON, FM_I2S_SLAVE, FM_I2S_48K); + #endif + if(ret){ + FM_LOG_ERR(D_MAIN,"pwron set I2S on error\n"); + return ret; + } + //we will disable 6620 fm chip analog output when use I2S path, set 0x3A bit2 = 0 + //MT6620_set_bits(0x3A, 0, MASK(2)); + FM_LOG_DBG(D_MAIN,"pwron set I2S on ok\n"); +#endif + + FM_LOG_INF(D_MAIN,"-MT6620 power on procedure\n"); + FM_LOG_NTC(D_MAIN,"pwron RX ok\n"); + + fm->powerup = FM_PWR_RX_ON; + fm_cxt->powerup = FM_PWR_RX_ON; + ret = down_interruptible(&fm_timer_mutex); + if(ret){ + FM_LOG_ERR(D_MAIN,"down fm_timer_mutex failed[ret=%d]\n", ret); + goto out; + } + timer_sys.onoff = FM_TIMER_SYS_ON; + //update timer + if(g_fm_config.timer < 1000){ + FM_LOG_WAR(D_TIMER,"timersys time err\n"); + g_fm_config.timer = FM_TIMER_TIMEOUT_DEFAULT; + } + mod_timer(&fm_timer, jiffies + g_fm_config.timer/(1000/HZ)); + up(&fm_timer_mutex); + //Tune to desired channel + if ((ret = fm_tune(fm, parm))){ + FM_LOG_ERR(D_MAIN,"Power on RX tune failed\n"); + return ret; + } + parm->err = FM_SUCCESS; + +out: + return ret; +} + +static int fm_antenna_switch(struct fm *fm, int antenna) +{ + int ret = 0; + + ret = MT6620_ANA_SWITCH(antenna); + if(ret){ + FM_LOG_ERR(D_MAIN,"Switch antenna failed\n"); + } + fm_cxt->rxcxt.ana = antenna; + FM_LOG_DBG(D_MAIN,"%s(),[ret=%d]!\n", __func__, ret); + return ret; +} + +/* + * fm_powerup_tx + */ +static int fm_powerup_tx(struct fm *fm, struct fm_tune_parm *parm) +{ + int ret = 0; + uint16_t pkt_size = 0; + + if(FM_PWR_TX_ON == fm->powerup){ + //FM TX already on + FM_LOG_NTC(D_MAIN,"%s, FM Tx already powered up\n", __func__); + parm->err = FM_BADSTATUS; + return 0; + }else if(FM_PWR_RX_ON == fm->powerup){ + //if Rx is on, we need pwr down RX first + ret = fm_powerdown(fm, FM_RX); + if(ret){ + FM_LOG_ERR(D_MAIN,"FM pwr down Rx fail!\n"); + return ret; + } + } + //for normal case + if (FALSE == fm->chipon){ + if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_FM)) { + FM_LOG_ERR(D_MAIN,"WMT turn on FM fail!\n"); + return -ENODEV; + } + FM_LOG_DBG(D_MAIN,"WMT turn on FM OK!\n"); + fm->chipon = TRUE; + } + + FM_LOG_INF(D_MAIN,"+MT6620 power on tx procedure\n"); + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_MAIN,"%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + return ret; + } + + if(tx_buf == NULL){ + FM_LOG_ERR(D_MAIN,"%s(): invalid tx_buf\n", __func__); + ret = -ERR_INVALID_BUF; + goto release_mutex; + } + memset(tx_buf, 0, TX_BUF_SIZE); + + pkt_size = mt6620_off_2_tx_shortANA(tx_buf, TX_BUF_SIZE); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT); + if(ret){ + FM_LOG_ERR(D_MAIN,"%s(): mt6620_off_2_tx_shortANA failed\n", __func__); + goto release_mutex; + } + + pkt_size = mt6620_dig_init(tx_buf, TX_BUF_SIZE); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT); + if(ret){ + FM_LOG_ERR(D_MAIN,"%s(): mt6620_dig_init failed\n", __func__); + goto release_mutex; + } +release_mutex: + up(&fm_cmd_mutex); + + if(ret) + return ret; + + FM_LOG_INF(D_MAIN,"-MT6620 power on tx procedure\n"); + FM_LOG_NTC(D_MAIN,"pwron tx ok\n"); + + fm->powerup = FM_PWR_TX_ON; + fm_cxt->powerup = FM_PWR_TX_ON; + ret = down_interruptible(&fm_timer_mutex); + if(ret){ + FM_LOG_ERR(D_MAIN,"down fm_timer_mutex failed[ret=%d]\n", ret); + goto out; + } + //update timer + if(g_fm_config.timer < 1000){ + FM_LOG_WAR(D_TIMER,"timersys time err\n"); + g_fm_config.timer = FM_TIMER_TIMEOUT_DEFAULT; + } + mod_timer(&fm_timer, jiffies + g_fm_config.timer/(1000/HZ)); + timer_sys.onoff = FM_TIMER_SYS_ON; + timer_sys.tx_pwr_ctrl_en = FM_TX_PWR_CTRL_ENABLE; + timer_sys.tx_rtc_ctrl_en = FM_TX_RTC_CTRL_ENABLE; + timer_sys.tx_desense_en = FM_TX_DESENSE_ENABLE; + up(&fm_timer_mutex); + //get temprature + if(mtk_wcn_wmt_therm_ctrl(WMTTHERM_ENABLE) != TRUE){ + FM_LOG_ERR(D_MAIN,"wmt_therm_ctrl, WMTTHERM_ENABLE failed\n"); + ret = -ERR_STP; + return ret; + } + if ((ret = fm_tune_tx(fm, parm))){ + FM_LOG_ERR(D_MAIN,"PowerUp Tx(), tune failed\n"); + return ret; + } + +#ifdef FM_DIGITAL_OUTPUT + #ifdef MT6573 //for MT6573 + if(get_chip_eco_ver() == CHIP_E1){ + ret = MT6620_I2S_Setting(FM_I2S_ON, FM_I2S_SLAVE, FM_I2S_48K); + }else{ + ret = MT6620_I2S_Setting(FM_I2S_ON, FM_I2S_SLAVE, FM_I2S_48K); + } + #else // for MT6575 + ret = MT6620_I2S_Setting(FM_I2S_ON, FM_I2S_SLAVE, FM_I2S_48K); + #endif + if(ret){ + FM_LOG_ERR(D_MAIN,"pwron Tx set I2S on error\n"); + return ret; + } + FM_LOG_DBG(D_MAIN,"pwron Tx set I2S on ok\n"); +#endif + + parm->err = FM_SUCCESS; + +out: + return ret; +} +/* + * fm_powerdown + */ +static int fm_powerdown(struct fm *fm, int type) +{ + int ret = 0; + uint16_t pkt_size = 0; + + FM_LOG_DBG(D_MAIN,"%s \n", __func__); + + if(down_interruptible(&fm_rxtx_mutex)){ + FM_LOG_ERR(D_TIMER, "%s(): get rx/tx mutex failed\n", __func__); + return -ERR_GET_MUTEX; + } + + if(((fm->powerup == FM_PWR_TX_ON) && (type == FM_RX)) || ((fm->powerup == FM_PWR_RX_ON) && (type == FM_TX))){ + FM_LOG_NTC(D_MAIN,"no need do pwr down\n"); + ret = 0; + goto out; + } + +#if (defined(FM_DIGITAL_INPUT) || defined(FM_DIGITAL_OUTPUT)) + if(MT6620_I2S_Setting(FM_I2S_OFF, FM_I2S_MASTER, FM_I2S_48K)){ + FM_LOG_ERR(D_MAIN,"pwrdown set I2S off error\n"); + goto out; + } + //MT6620_set_bits(0x3A, BITn(2), MASK(2)); + FM_LOG_DBG(D_MAIN,"pwrdown set I2S off ok\n"); +#endif + + if (down_interruptible(&fm_cmd_mutex)){ + FM_LOG_ERR(D_CMD|D_ALL, "%s(): get mutex failed\n", __func__); + ret = -ERR_GET_MUTEX; + goto out; + } + if(tx_buf == NULL){ + FM_LOG_ERR(D_MAIN,"invalid tx_buf\n"); + up(&fm_cmd_mutex); + goto out; + } + memset(tx_buf, 0, TX_BUF_SIZE); + pkt_size = mt6620_powerdown(tx_buf, TX_BUF_SIZE); + ret = fm_send_wait_timeout(tx_buf, pkt_size, + FLAG_EN, SW_RETRY_CNT, EN_TIMEOUT); + up(&fm_cmd_mutex); + FM_LOG_INF(D_CMD,"+fm_cmd_mutex\n"); + if(ret){ + FM_LOG_ERR(D_MAIN,"%s(): pwrdown failed\n", __func__); + goto out; + } + + ret = down_interruptible(&fm_timer_mutex); + if(ret){ + FM_LOG_ERR(D_MAIN,"down fm_timer_mutex failed[ret=%d]\n", ret); + goto out; + } + timer_sys.onoff = FM_TIMER_SYS_OFF; + timer_sys.rds_reset_en = FM_RDS_RST_DISABLE; + timer_sys.tx_pwr_ctrl_en = FM_TX_PWR_CTRL_DISABLE; + timer_sys.tx_rtc_ctrl_en = FM_TX_RTC_CTRL_DISABLE; + timer_sys.tx_desense_en = FM_TX_DESENSE_DISABLE; + up(&fm_timer_mutex); + if(fm->powerup == FM_PWR_TX_ON){ + if(mtk_wcn_wmt_therm_ctrl(WMTTHERM_DISABLE) != TRUE){ + FM_LOG_ERR(D_MAIN,"wmt_therm_ctrl, WMTTHERM_DISABLE failed\n"); + ret = -ERR_STP; + } + } + fm->RDS_Data_ready = true; //info FM APP to stop read RDS + memset(fm->pstRDSData, 0, sizeof(RDSData_Struct)); + wake_up_interruptible(&fm->read_wait); + fm->powerup = FM_PWR_OFF; + fm_cxt->powerup = FM_PWR_OFF; + FM_LOG_NTC(D_MAIN,"pwrdown %s ok\n", (type==FM_TX)? "TX" : "RX"); +out: + up(&fm_rxtx_mutex); + return ret; +} + +/* + * fm_seek + */ +static int fm_seek(struct fm *fm, struct fm_seek_parm *parm) +{ + int ret = 0; + uint16_t seekdir, space; + + if (!fm->powerup){ + parm->err = FM_BADSTATUS; + return -EPERM; + } + + if (parm->space == FM_SPACE_100K){ + space = MT6620_FM_SPACE_100K; + }else if (parm->space == FM_SPACE_200K) { + space = MT6620_FM_SPACE_200K; + }else{ + //default + space = MT6620_FM_SPACE_100K; + } + + if (parm->band == FM_BAND_UE){ + fm->min_freq = 875; + fm->max_freq = 1080; + }else if (parm->band == FM_BAND_JAPAN){ + fm->min_freq = 760; + fm->max_freq = 900; + }else if (parm->band == FM_BAND_JAPANW){ + fm->min_freq = 760; + fm->max_freq = 1080; + }else if(parm->band == FM_BAND_SPECIAL){ + fm->min_freq = FMR_BAND_FREQ_L; + fm->max_freq = FMR_BAND_FREQ_H; + }else{ + FM_LOG_ERR(D_MAIN,"band:%d out of range\n", parm->band); + parm->err = FM_EPARM; + return -EPERM; + } + + if (parm->freq < fm->min_freq || parm->freq > fm->max_freq){ + FM_LOG_ERR(D_MAIN,"freq:%d out of range\n", parm->freq); + parm->err = FM_EPARM; + return -EPERM; + } + + if (parm->seekdir == FM_SEEK_UP){ + seekdir = MT6620_FM_SEEK_UP; + }else{ + seekdir = MT6620_FM_SEEK_DOWN; + } + +#ifdef FMDEBUG + if (parm->seekdir == FM_SEEK_UP) + FM_LOG_DBG(D_MAIN,"seek %d up\n", parm->freq); + else + FM_LOG_DBG(D_MAIN,"seek %d down\n", parm->freq); +#endif + + // seek successfully + if(!(ret = MT6620_Seek(fm->min_freq, fm->max_freq, &(parm->freq), seekdir, space))){ + parm->err = FM_SUCCESS; + }else{ + parm->err = FM_SEEK_FAILED; + } + + //ret = do_cmd_send(fm, NULL, 0, FM_COM_CMD_SEEK, NULL); + + return ret; +} + +/* + * fm_scan + */ +static int fm_scan(struct fm *fm, struct fm_scan_parm *parm) +{ + int ret = 0; + uint16_t scandir = MT6620_FM_SCAN_UP, space; + + if (!fm->powerup){ + parm->err = FM_BADSTATUS; + return -EPERM; + } + + if (parm->space == FM_SPACE_100K){ + space = MT6620_FM_SPACE_100K; + }else if (parm->space == FM_SPACE_200K) { + space = MT6620_FM_SPACE_200K; + }else{ + //default + space = MT6620_FM_SPACE_100K; + } + + if(parm->band == FM_BAND_UE){ + fm->min_freq = 875; + fm->max_freq = 1080; + }else if(parm->band == FM_BAND_JAPAN){ + fm->min_freq = 760; + fm->max_freq = 900; + }else if(parm->band == FM_BAND_JAPANW){ + fm->min_freq = 760; + fm->max_freq = 1080; + }else if(parm->band == FM_BAND_SPECIAL){ + fm->min_freq = FMR_BAND_FREQ_L; + fm->max_freq = FMR_BAND_FREQ_H; + }else{ + FM_LOG_ERR(D_ALL,"fm_scan band:%d out of range\n", parm->band); + parm->err = FM_EPARM; + return -EPERM; + } + + if(!(ret = MT6620_Scan(fm->min_freq, fm->max_freq, &(parm->freq), + parm->ScanTBL, &(parm->ScanTBLSize), scandir, space))){ + parm->err = FM_SUCCESS; + }else{ + FM_LOG_ERR(D_MAIN,"fm_scan failed\n"); + parm->err = FM_SEEK_FAILED; + } + + return ret; +} + +/* + * fm_get_rssi_after_scan + * + * get the rssi per channel, we need only use fast tune instead of normal tune to save time + * @fm -- main data struct of fm driver + * @req -- input freq, and output rssi + * + */ +static int fm_get_rssi_after_scan(struct fm *fm, struct fm_rssi_req *req) +{ + int ret = 0; + int i, j; + int tmp = 0; + int total = 0; + + req->num = (req->num > sizeof(req->cr)) ? sizeof(req->cr) : req->num; + for(i = 0; i < req->num; i++){ + ret = MT6620_Fast_SetFreq(req->cr[i].freq); + if(ret) + return ret; + //get rssi, if need multi read, do it and get the average val + req->read_cnt = (req->read_cnt < 1) ? 1 : req->read_cnt; + req->read_cnt = (req->read_cnt > 10) ? 10 : req->read_cnt; + tmp = 0; + total = 0; + for(j = 0; j < req->read_cnt; j++){ + ret = MT6620_GetCurRSSI(&tmp); + if(ret) + return ret; + Delayms(2); + total += tmp; + } + req->cr[i].rssi = total/req->read_cnt; + } + + return ret; +} + +static int fm_get_hw_info(struct fm *pfm, struct fm_hw_info *req) +{ + int ret = 0; + ENUM_WMTHWVER_TYPE_T eco_ver; + + eco_ver = mtk_wcn_wmt_hwver_get(); + req->chip_id = 0x00006620; + req->eco_ver = (int)eco_ver; + req->rom_ver = 0x00000002; + req->patch_ver = 0x00000111; + req->reserve = 0x00000000; + + return ret; +} + +//volume?[0~15] +static int fm_setvol(struct fm *fm, uint32_t vol) +{ + uint8_t tmp_vol; + int ret = 0; + + tmp_vol = vol*3; + ret = MT6620_SetVol(tmp_vol); + fm_cxt->rxcxt.vol = vol; + + return ret; +} + +static int fm_getvol(struct fm *fm, uint32_t *vol) +{ + uint8_t tmp_vol; + int ret = 0; + + ret = MT6620_GetVol(&tmp_vol); + if(tmp_vol == FM_VOL_MAX) + *vol = 15; + else + *vol = (tmp_vol/3); + + return ret; +} + +static int fm_getrssi(struct fm *fm, int *rssi) +{ + int ret = 0; + + ret = MT6620_GetCurRSSI(rssi); + + return ret; +} + +/* + * fm_print_curCQI -- print cur freq's CQI + * @cur_freq, current frequency + * If OK, return 0, else error code + */ +static int fm_print_curCQI(uint16_t cur_freq) +{ + int ret = 0; + uint16_t rssi = 0; + uint16_t pamd = 0; + uint16_t mr = 0; + + if((ret = MT6620_write(FM_PGSEL, FM_PG0))) + return ret; + if((ret = MT6620_read(FM_RSSI_IND, &rssi))) + return ret; + if((ret = MT6620_read(FM_PAMD_IND, &pamd))) + return ret; + if((ret = MT6620_read(FM_MR_IND, &mr))) + return ret; + + FM_LOG_NTC(D_MAIN,"FREQ=%d, RSSI=0x%04x, PAMD=0x%04x, MR=0x%04x\n", (int)cur_freq, rssi, pamd, mr); + return ret; +} + +/* + * fm_tune + */ +static int fm_tune(struct fm *fm, struct fm_tune_parm *parm) +{ + int ret = 0; + int hl_side = -1; + int freq_avoid = -1; + ENUM_WMTHWVER_TYPE_T hw_ver; + + FM_LOG_DBG(D_MAIN,"%s\n", __func__); + + if (!fm->powerup){ + parm->err = FM_BADSTATUS; + return -ERR_INVALID_PARA; + } + + if (parm->band == FM_BAND_UE){ + fm->min_freq = 875; + fm->max_freq = 1080; + }else if (parm->band == FM_BAND_JAPAN){ + fm->min_freq = 760; + fm->max_freq = 900; + }else if (parm->band == FM_BAND_JAPANW){ + fm->min_freq = 760; + fm->max_freq = 1080; + }else{ + parm->err = FM_EPARM; + return -ERR_INVALID_PARA; + } + fm->band = parm->band; + + if (unlikely(parm->freq < fm->min_freq || parm->freq > fm->max_freq)){ + parm->err = FM_EPARM; + return -ERR_INVALID_PARA; + } + + if((ret = MT6620_RampDown())) + return ret; + + //high low side switch + //adpll freq avoid + //mcu freq avoid + if(priv.state == INITED){ + FM_LOG_INF(D_MAIN,"%s, hl_side switch[0x%08x]\n", __func__, (unsigned int)priv.priv_tbl.hl_side); + if(priv.priv_tbl.hl_side != NULL){ + if((ret = priv.priv_tbl.hl_side(parm->freq, &hl_side))) + return ret; + } + FM_LOG_NTC(D_MAIN,"%s, [hl_side=%d]\n", __func__, hl_side); + + FM_LOG_INF(D_MAIN,"%s, adpll freq avoid[0x%08x]\n", __func__, (unsigned int)priv.priv_tbl.adpll_freq_avoid); + if(priv.priv_tbl.adpll_freq_avoid != NULL){ + if((ret = priv.priv_tbl.adpll_freq_avoid(parm->freq, &freq_avoid))) + return ret; + } + FM_LOG_NTC(D_MAIN,"%s, adpll [freq_avoid=%d]\n", __func__, freq_avoid); + + hw_ver = mtk_wcn_wmt_hwver_get(); + if(hw_ver >= WMTHWVER_MT6620_E3){ + FM_LOG_INF(D_MAIN,"%s, mcu freq avoid[0x%08x]\n", __func__, (unsigned int)priv.priv_tbl.mcu_freq_avoid); + if(priv.priv_tbl.mcu_freq_avoid != NULL){ + if((ret = priv.priv_tbl.mcu_freq_avoid(parm->freq, &freq_avoid))) + return ret; + } + FM_LOG_NTC(D_MAIN,"%s, mcu [freq_avoid=%d]\n", __func__, freq_avoid); + }else{ + FM_LOG_NTC(D_MAIN,"%s, no need do mcu freq avoid[hw_ver=%d]\n", __func__, hw_ver); + } + } + + ret = MT6620_SetFreq(parm->freq); + + ret = fm_print_curCQI(_current_frequency); + + return ret; +} + +/* + * fm_tune_tx + */ +static int fm_tune_tx(struct fm *fm, struct fm_tune_parm *parm) +{ + int ret = 0; + FM_LOG_DBG(D_MAIN,"%s\n", __func__); + + if (!fm->powerup){ + parm->err = FM_BADSTATUS; + return -EPERM; + } + + if (parm->band == FM_BAND_UE){ + fm->min_freq = 875; + fm->max_freq = 1080; + }else if (parm->band == FM_BAND_JAPAN){ + fm->min_freq = 760; + fm->max_freq = 900; + }else if (parm->band == FM_BAND_JAPANW){ + fm->min_freq = 760; + fm->max_freq = 1080; + }else{ + parm->err = FM_EPARM; + return -ERR_INVALID_PARA; + } + + if (unlikely(parm->freq < fm->min_freq || parm->freq > fm->max_freq)){ + parm->err = FM_EPARM; + return -ERR_INVALID_PARA; + } + + //we will do rampdown in tune sequence, it's do nothing here + while(0){ + if((ret = MT6620_RampDown_Tx())) + return ret; + } + + //tune to desired channel + ret = MT6620_SetFreq_Tx(parm->freq); + return ret; +} + +/*********************************************************** +Function: fm_tx_scan() + +Description: get the valid channels for fm tx function + +Para: fm--->fm driver global info + parm--->input/output paramater + +Return: 0, if success; error code, if failed +***********************************************************/ +static int fm_tx_scan(struct fm *fm, struct fm_tx_scan_parm *parm) +{ + int ret = 0; + uint16_t scandir = 0; + uint16_t space = FM_SPACE_100K; + + if (!fm->powerup){ + parm->err = FM_BADSTATUS; + FM_LOG_ERR(D_ALL,"fm_tx_scan failed, [fm->powerup=%d]\n", fm->powerup); + return -EPERM; + } + + if(FM_TX_SUPPORT != atomic_read(&fm->tx_support)){ + parm->err = FM_BADSTATUS; + FM_LOG_ERR(D_ALL,"fm_tx_scan failed, [fm->tx_support=%d]\n", atomic_read(&fm->tx_support)); + return -EPERM; + } + + switch(parm->scandir){ + case MT6620_FM_SCAN_UP: + scandir = 0; + break; + case MT6620_FM_SCAN_DOWN: + scandir = 1; + break; + default: + scandir = 0; + break; + } + + switch(parm->space){ + case FM_SPACE_100K: + space = 1; + break; + case FM_SPACE_200K: + space = 2; + break; + default: + space = 1; + break; + } + + switch(parm->band){ + case FM_BAND_UE: + fm->min_freq = 875; + fm->max_freq = 1080; + break; + case FM_BAND_JAPAN: + fm->min_freq = 760; + fm->max_freq = 900; + break; + case FM_BAND_JAPANW: + fm->min_freq = 760; + fm->max_freq = 1080; + break; + default: + parm->err = FM_EPARM; + FM_LOG_ERR(D_ALL,"fm_tx_scan: bad band para\n"); + return -EPERM; + break; + } + + if (unlikely((parm->freq < fm->min_freq) || (parm->freq > fm->max_freq))){ + parm->err = FM_EPARM; + return -EPERM; + } + + if (unlikely(parm->ScanTBLSize < TX_SCAN_MIN || parm->ScanTBLSize > TX_SCAN_MAX)){ + parm->err = FM_EPARM; + return -EPERM; + } + + //make sure use short antenna, and you can't use "fm_antenna_switch()" because it will record ana context for RX + ret = MT6620_ANA_SWITCH(FM_SHORT_ANA); + if(ret){ + FM_LOG_ERR(D_MAIN,"switch to short ana failed\n"); + return ret; + } + + //do tx scan + if(!(ret = MT6620_TxScan(fm->min_freq, fm->max_freq, &(parm->freq), + parm->ScanTBL, &(parm->ScanTBLSize), scandir, space))){ + parm->err = FM_SUCCESS; + }else{ + FM_LOG_ERR(D_MAIN,"fm_tx_scan failed\n"); + parm->err = FM_SCAN_FAILED; + } + return ret; +} + +static int fm_rds_tx(struct fm *fm, struct fm_rds_tx_parm *parm) +{ + int ret = 0; + FM_LOG_DBG(D_RDS,"+%s()\n", __func__); + if(parm->other_rds_cnt > 29){ + parm->err = FM_EPARM; + FM_LOG_WAR(D_RDS,"%s(), [other_rds_cnt=%d]\n", __func__, parm->other_rds_cnt); + ret = -ERR_INVALID_PARA; + goto out; + } + + ret = MT6620_Rds_Tx_Enable(1); + if(ret){ + FM_LOG_WAR(D_RDS,"%s(), MT6620_Rds_Tx_Enable failed!\n", __func__); + goto out; + } + ret = MT6620_Rds_Tx(parm->pi, parm->ps, parm->other_rds, parm->other_rds_cnt); + fm_cxt->txcxt.rdsTxOn = true; + fm_cxt->txcxt.pi = parm->pi; + memcpy(fm_cxt->txcxt.ps, parm->ps,sizeof(parm->ps)); + memcpy(fm_cxt->txcxt.other_rds, parm->other_rds,sizeof(parm->other_rds)); + fm_cxt->txcxt.other_rds_cnt = parm->other_rds_cnt; +out: + FM_LOG_DBG(D_RDS,"-%s()\n", __func__); + return ret; +} + +static int fm_over_bt(struct fm *fm, int enable) +{ + int ret = 0; + + ret = MT6620_FMOverBT(enable); + if(ret){ + FM_LOG_WAR(D_MAIN,"%s(),failed!\n", __func__); + } + fm_cxt->rxcxt.ViaBt = enable; + FM_LOG_DBG(D_MAIN,"%s(),[ret=%d]!\n", __func__, ret); + return ret; +} + +static int fm_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int cnt = 0; + struct fm *fm = fm_cb; + + FM_LOG_DBG(D_MAIN, "Enter fm_proc_read.\n"); + if(off != 0) + return 0; + if (fm != NULL && fm->chipon){ + if(fm->powerup == FM_PWR_TX_ON){ + cnt = sprintf(page, "2\n"); + }else if(fm->powerup == FM_PWR_RX_ON){ + cnt = sprintf(page, "1\n"); + } + } else { + cnt = sprintf(page, "0\n"); + } + *eof = 1; + FM_LOG_DBG(D_MAIN, "Leave fm_proc_read. FM_on = %s\n", page); + return cnt; +} + +static int fm_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) +{ + char tmp_buf[11] = {0}; + uint32_t copysize; + + copysize = (count < (sizeof(tmp_buf) - 1)) ? count : (sizeof(tmp_buf) - 1); + if (copy_from_user(tmp_buf, buffer, copysize)){ + FM_LOG_ERR(D_ALL, "failed copy_from_user\n"); + return -EFAULT; + } + + if (sscanf(tmp_buf, "%x", &g_dbg_level) != 1){ + FM_LOG_ERR(D_ALL, "failed g_dbg_level = 0x%x\n", g_dbg_level); + return -EFAULT; + } + + FM_LOG_WAR(D_MAIN, "success g_dbg_level = 0x%x\n", g_dbg_level); + return count; +} + +static int fmconfig_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int cnt = 0; + //struct fm *fm = fm_cb; + + FM_LOG_DBG(D_MAIN, "Enter fm_config_proc_read.\n"); + if(off != 0) + return 0; + cnt = sprintf(page, "[t]timerSys: %d ms\n", g_fm_config.timer); + cnt += sprintf(page+cnt, "[v]vcoOff: %d s\n", g_fm_config.vcooff); + cnt += sprintf(page+cnt, "[v]vcoOn: %d ms\n", g_fm_config.vcoon); + cnt += sprintf(page+cnt, "[p]pwrctlTx: %d s\n", g_fm_config.txpwrctl); + cnt += sprintf(page+cnt, "[r]rdsRst: %d s\n", g_fm_config.rdsrst); + *eof = 1; + FM_LOG_DBG(D_MAIN, "Leave fm_config_proc_read. Config = %s\n", page); + return cnt; +} + +static int fmconfig_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) +{ + char tmp_buf[100] = {0}; + uint32_t copysize; + + copysize = (count < (sizeof(tmp_buf) - 1)) ? count : (sizeof(tmp_buf) - 1); + if (copy_from_user(tmp_buf, buffer, copysize)){ + FM_LOG_ERR(D_ALL, "failed copy_from_user\n"); + return -EFAULT; + } + + switch(tmp_buf[0]){ + case 'v': + switch(tmp_buf[1]){ + case 'u': + //FM TX vco tracking ON duiration setting + if (sscanf(&tmp_buf[2], "%d", &g_fm_config.vcoon) != 1){ + FM_LOG_ERR(D_ALL, "failed vcoon = %d\n", g_fm_config.vcoon); + return -EFAULT; + } + g_fm_config.vcoon = (g_fm_config.vcoon < FM_TX_VCO_ON_MIN) ? FM_TX_VCO_ON_MIN : g_fm_config.vcoon; + g_fm_config.vcoon = (g_fm_config.vcoon > FM_TX_VCO_ON_MAX) ? FM_TX_VCO_ON_MAX : g_fm_config.vcoon; + FM_LOG_WAR(D_MAIN, "success vcoon = %d\n", g_fm_config.vcoon); + break; + case 'd': + //FM TX vco tracking OFF duiration setting + if (sscanf(&tmp_buf[2], "%d", &g_fm_config.vcooff) != 1){ + FM_LOG_ERR(D_ALL, "failed vcooff = %d\n", g_fm_config.vcooff); + return -EFAULT; + } + g_fm_config.vcooff = (g_fm_config.vcooff < FM_TX_VCO_OFF_MIN) ? FM_TX_VCO_OFF_MIN : g_fm_config.vcooff; + g_fm_config.vcooff = (g_fm_config.vcooff > FM_TX_VCO_OFF_MAX) ? FM_TX_VCO_OFF_MAX : g_fm_config.vcooff; + FM_LOG_WAR(D_MAIN, "success vcooff = %d\n", g_fm_config.vcooff); + break; + default: + FM_LOG_ERR(D_MAIN, "Para 2 error\n"); + break; + } + break; + case 't': + if (sscanf(&tmp_buf[1], "%d", &g_fm_config.timer) != 1){ + FM_LOG_ERR(D_ALL, "failed timer = %d\n", g_fm_config.timer); + return -EFAULT; + } + g_fm_config.timer = (g_fm_config.timer < FM_TIMER_TIMEOUT_MIN) ? FM_TIMER_TIMEOUT_MIN : g_fm_config.timer; + g_fm_config.timer = (g_fm_config.timer > FM_TIMER_TIMEOUT_MAX) ? FM_TIMER_TIMEOUT_MAX : g_fm_config.timer; + FM_LOG_WAR(D_MAIN, "success timer = %d\n", g_fm_config.timer); + break; + case 'r': + if (sscanf(&tmp_buf[1], "%d", &g_fm_config.rdsrst) != 1){ + FM_LOG_ERR(D_ALL, "failed rdsrst = %d\n", g_fm_config.rdsrst); + return -EFAULT; + } + g_fm_config.rdsrst = (g_fm_config.rdsrst < FM_RDS_RST_INVAL_MIN) ? FM_RDS_RST_INVAL_MIN : g_fm_config.rdsrst; + g_fm_config.rdsrst = (g_fm_config.rdsrst > FM_RDS_RST_INVAL_MAX) ? FM_RDS_RST_INVAL_MAX : g_fm_config.rdsrst; + FM_LOG_WAR(D_MAIN, "success rdsrst = %d\n", g_fm_config.rdsrst); + break; + case 'p': + if (sscanf(&tmp_buf[1], "%d", &g_fm_config.txpwrctl) != 1){ + FM_LOG_ERR(D_ALL, "failed txpwrctl = %d\n", g_fm_config.txpwrctl); + return -EFAULT; + } + g_fm_config.txpwrctl = (g_fm_config.txpwrctl < FM_RDS_RST_INVAL_MIN) ? FM_RDS_RST_INVAL_MIN : g_fm_config.txpwrctl; + g_fm_config.txpwrctl = (g_fm_config.txpwrctl > FM_RDS_RST_INVAL_MAX) ? FM_RDS_RST_INVAL_MAX : g_fm_config.txpwrctl; + FM_LOG_WAR(D_MAIN, "success txpwrctl = %d\n", g_fm_config.txpwrctl); + break; + case 's': + fm_hw_reset(); + FM_LOG_WAR(D_MAIN, "do fm_hw_reset\n"); + break; + case 'm': + do_cmd_send(NULL, NULL, 0, FM_COM_CMD_TEST, NULL); + break; + default: + FM_LOG_ERR(D_MAIN, "Para 1 error\n"); + break; + } + return count; +} + +int fm_priv_register(struct fm_priv *pri, struct fm_op *op) +{ + int ret = 0; + //Basic functions. + + FM_LOG_NTC(D_INIT,"%s(), [pri=0x%08x][op=0x%08x]\n", __func__, (unsigned int)pri, (unsigned int)op); + FMR_ASSERT(pri); + FMR_ASSERT(op); + + priv.priv_tbl.hl_side = pri->priv_tbl.hl_side; + priv.priv_tbl.adpll_freq_avoid = pri->priv_tbl.adpll_freq_avoid; + priv.priv_tbl.mcu_freq_avoid = pri->priv_tbl.mcu_freq_avoid; + priv.priv_tbl.tx_pwr_ctrl = pri->priv_tbl.tx_pwr_ctrl; + priv.priv_tbl.rtc_drift_ctrl = pri->priv_tbl.rtc_drift_ctrl; + priv.priv_tbl.tx_desense_wifi = pri->priv_tbl.tx_desense_wifi; + priv.state = INITED; + priv.data = NULL; + + op->op_tbl.read = MT6620_read; + op->op_tbl.write = MT6620_write; + op->op_tbl.setbits = MT6620_set_bits; + op->op_tbl.rampdown = MT6620_RampDown; + op->state = INITED; + op->data = NULL; + + return ret; +} + +int fm_priv_unregister(struct fm_priv *pri, struct fm_op *op) +{ + int ret = 0; + //Basic functions. + + FM_LOG_NTC(D_INIT,"%s(), [pri=0x%08x][op=0x%08x]\n", __func__, (unsigned int)pri, (unsigned int)op); + + FMR_ASSERT(pri); + FMR_ASSERT(op); + + priv.priv_tbl.hl_side = NULL; + priv.priv_tbl.adpll_freq_avoid = NULL; + priv.priv_tbl.mcu_freq_avoid = NULL; + priv.priv_tbl.tx_pwr_ctrl = NULL; + priv.priv_tbl.rtc_drift_ctrl = NULL; + priv.priv_tbl.tx_desense_wifi = NULL; + priv.state = UNINITED; + priv.data = NULL; + + op->op_tbl.read = NULL; + op->op_tbl.write = NULL; + op->op_tbl.setbits = NULL; + op->op_tbl.rampdown = NULL; + op->state = UNINITED; + op->data = NULL; + + return ret; +} + +static int __init mt_fm_probe(void) +{ + int err = -1; + FM_LOG_NTC(D_INIT,"%s()\n", __func__); + + spin_lock_init(&flag_lock); + + if ((err = fm_init())){ + FM_LOG_ALT(D_ALL, "fm_init ERR:%d\n", err); + } + + return err; +} + +static void __exit mt_fm_remove(void) +{ + FM_LOG_NTC(D_INIT,"%s()\n", __func__); + fm_destroy(fm_cb); + + return; +} + +EXPORT_SYMBOL(fm_priv_register); +EXPORT_SYMBOL(fm_priv_unregister); +EXPORT_SYMBOL(g_dbg_level); + +module_init(mt_fm_probe); +module_exit(mt_fm_remove); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MediaTek MT6620 FM Driver"); +MODULE_AUTHOR("Mike "); + diff --git a/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.h b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.h new file mode 100755 index 000000000000..4b76d84a3aca --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm.h @@ -0,0 +1,597 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#ifndef __MT6620_FM_H__ +#define __MT6620_FM_H__ + +#include +#include +#include +#include "fm.h" + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define RDS_RX_BLOCK_PER_GROUP (4) +#define RDS_RX_GROUP_SIZE (2*RDS_RX_BLOCK_PER_GROUP) +#define MAX_RDS_RX_GROUP_CNT (12) +#define FM_RDS_ENABLE 0x01 // 1: enable RDS, 0:disable RDS + + +/******************DBG level added by DDB************************/ +#define D_BASE 4 +#define D_IOCTL (1 << (D_BASE+0)) +#define D_RX (1 << (D_BASE+1)) +#define D_TIMER (1 << (D_BASE+2)) +#define D_BLKC (1 << (D_BASE+3)) +#define D_G0 (1 << (D_BASE+4)) +#define D_G1 (1 << (D_BASE+5)) +#define D_G2 (1 << (D_BASE+6)) +#define D_G3 (1 << (D_BASE+7)) +#define D_G4 (1 << (D_BASE+8)) +#define D_G14 (1 << (D_BASE+9)) +#define D_RAW (1 << (D_BASE+10)) +#define D_RDS (1 << (D_BASE+11)) +#define D_INIT (1 << (D_BASE+12)) +#define D_MAIN (1 << (D_BASE+13)) +#define D_CMD (1 << (D_BASE+14)) +#define D_ALL 0xfffffff0 + +#define L0 0x00000000 // EMERG, system will crush +#define L1 0x00000001 // ALERT, need action in time +#define L2 0x00000002 // CRIT, important HW or SW operation failed +#define L3 0x00000003 // ERR, normal HW or SW ERR +#define L4 0x00000004 // WARNING, importan path or somewhere may occurs err +#define L5 0x00000005 // NOTICE, normal case +#define L6 0x00000006 // INFO, print info if need +#define L7 0x00000007 // DEBUG, for debug info + +#define FM_EMERG L0 +#define FM_ALERT L1 +#define FM_CRIT L2 +#define FM_ERR L3 +#define FM_WARNING L4 +#define FM_NOTICE L5 +#define FM_INFO L6 +#define FM_DEBUG L7 + +extern uint32_t g_dbg_level; + +#if 0 +#define WCN_DBG(flag, fmt, args...) \ + do { \ + if ((((flag)&0x0000000f)<=(g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_ALERT "[" #flag "]" fmt, ## args); \ + } \ + } while(0) +#endif + +//#define FM_USE_XLOG + +#ifdef FM_USE_XLOG +#include +#define FM_DRV_LOG_TAG "FM_DRV" + +#define FM_LOG_DBG(flag, fmt, args...) \ + do{ \ + if((FM_DEBUG <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_INFO, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_INF(flag, fmt, args...) \ + do{ \ + if((FM_INFO <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_INFO, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_NTC(flag, fmt, args...) \ + do{ \ + if((FM_NOTICE <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_WARN, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_WAR(flag, fmt, args...) \ + do{ \ + if((FM_WARNING <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_WARN, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_ERR(flag, fmt, args...) \ + do{ \ + if((FM_ERR <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_ERROR, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_CRT(flag, fmt, args...) \ + do{ \ + if((FM_CRIT <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_FATAL, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_ALT(flag, fmt, args...) \ + do{ \ + if((FM_ALERT <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_FATAL, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_EMG(flag, fmt, args...) \ + do{ \ + if((FM_EMERG <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + xlog_printk(ANDROID_LOG_FATAL, FM_DRV_LOG_TAG, "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#else + +#define FM_LOG_DBG(flag, fmt, args...) \ + do{ \ + if((FM_DEBUG <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_DEBUG "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_INF(flag, fmt, args...) \ + do{ \ + if((FM_INFO <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_INFO "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_NTC(flag, fmt, args...) \ + do{ \ + if((FM_NOTICE <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_NOTICE "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_WAR(flag, fmt, args...) \ + do{ \ + if((FM_WARNING <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_WARNING "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_ERR(flag, fmt, args...) \ + do{ \ + if((FM_ERR <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_ERR "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_CRT(flag, fmt, args...) \ + do{ \ + if((FM_CRIT <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_CRIT "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_ALT(flag, fmt, args...) \ + do{ \ + if((FM_ALERT <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_ALERT "[" #flag "]" fmt, ## args); \ + } \ + } while(0) + +#define FM_LOG_EMG(flag, fmt, args...) \ + do{ \ + if((FM_EMERG <= (g_dbg_level&0x0000000f)) && ((flag)&0xfffffff0)& g_dbg_level) { \ + printk(KERN_EMERG "[" #flag "]" fmt, ## args); \ + } \ + } while(0) +#endif + +#define BITn(n) (uint16_t)(1<<(n)) +#define MASK(n) (uint16_t)(~(1<<(n))) + +#define FM_COM_ASSERT(n) {\ + if(!(n)){\ + FM_LOG_ERR(D_ALL, "%s(), %d\n", __func__, __LINE__);\ + return -EFAULT;\ + }\ + } + + +typedef enum +{ + FM_TX_NOT_SUPPORT = 0, + FM_TX_SUPPORT +}fm_tx_support_flag; + +typedef enum +{ + FM_RDS_TX_NOT_SUPPORT = 0, + FM_RDS_TX_SUPPORT +}fm_rds_tx_support_flag; + +typedef enum +{ + FM_RDS_TX_DISENABLE = 0, + FM_RDS_TX_ENABLE +}fm_rds_tx_enable_state; + +typedef enum +{ + FM_OVER_BT_DISABLE = 0, + FM_OVER_BT_ENABLE +}fm_over_bt_enable_state; + +typedef enum +{ + FM_LONG_ANA = 0, + FM_SHORT_ANA +}fm_antenna_type; + +typedef struct +{ + uint16_t blkA; + uint16_t blkB; + uint16_t blkC; + uint16_t blkD; + uint16_t cbc; //correct bit cnt + uint16_t crc; //crc checksum +}rds_packet_struct; + +struct rds_rx +{ + uint16_t sin; + uint16_t cos; + rds_packet_struct data[MAX_RDS_RX_GROUP_CNT]; +}; + +typedef enum fm_pwr_status{ + FM_PWR_OFF = 0, + FM_PWR_RX_ON = 1, + FM_PWR_TX_ON = 2, + FM_PWR_MAX +}fm_pwr_status; + +struct fm { + volatile uint ref; + volatile bool chipon; //MT6620 chip power state + volatile fm_pwr_status powerup; //FM module power state + atomic_t tx_support; //FM Tx support flag, 1: support, 0: not support + int tx_pwr; + atomic_t rds_tx_support; //FM RDS Tx support flag, 1: support, 0: not support + atomic_t rds_tx_enable; //FM RDS Tx enable state, 1:enable RDS Tx function, 0:disable + atomic_t over_bt_enable; //FM over BT enable state, 1:enable, 0:disable + uint16_t chip_id; + uint16_t device_id; + dev_t dev_t; + uint16_t min_freq; // KHz + uint16_t max_freq; // KHz + uint8_t band; // TODO + struct class *cls; + struct device *dev; + struct cdev cdev; + wait_queue_head_t read_wait; + volatile bool RDS_Data_ready; + RDSData_Struct *pstRDSData; + struct rds_group_cnt rds_gc; + struct workqueue_struct *fm_workqueue; /* fm rx handling */ + struct workqueue_struct *fm_timer_workqueue; /* fm rds reset handling */ + struct work_struct fm_rds_reset_work; + struct work_struct fm_tx_power_ctrl_work; + struct work_struct fm_tx_rtc_ctrl_work; + struct work_struct fm_tx_desense_wifi_work; + struct work_struct fm_rst_recover_work; + struct work_struct fm_subsys_recover_work; + struct work_struct fm_rx_work; +}; + +struct fm_rx_cxt{ + int audioPath; //I2S or Analog + int vol; + int mute; + int rdsOn; + int ana; //long/short antenna + int ViaBt; //FM over bt controller +}; + +struct fm_tx_cxt{ + int audioPath; //I2S or Analog + int rdsTxOn; + uint16_t pi; + uint16_t ps[12]; // 4 ps + uint16_t other_rds[87]; // 0~29 other groups + uint8_t other_rds_cnt; // # of other group +}; + +struct fm_context{ + volatile int ref; + volatile bool chipon; + fm_pwr_status powerup; + volatile int16_t freq; + struct fm_rx_cxt rxcxt; + struct fm_tx_cxt txcxt; +}; + +struct fm_config{ + struct proc_dir_entry *proc; + uint32_t vcoon; + uint32_t vcooff; + uint32_t timer; + uint32_t txpwrctl; + uint32_t rdsrst; +}; + +typedef struct fm_timer_sys{ + volatile uint32_t count; + volatile uint8_t onoff; + volatile uint8_t rds_reset_en; + volatile uint8_t tx_pwr_ctrl_en; + volatile uint8_t tx_rtc_ctrl_en; + volatile uint8_t tx_desense_en; +}fm_timer_sys; + +enum{ + FM_TIMER_SYS_OFF, + FM_TIMER_SYS_ON, + FM_TIMER_SYS_MAX +}; + +enum{ + FM_RDS_RST_DISABLE, + FM_RDS_RST_ENABLE, + FM_RDS_RST_MAX +}; + +enum{ + FM_TX_PWR_CTRL_DISABLE, + FM_TX_PWR_CTRL_ENABLE, + FM_TX_PWR_CTRL_MAX +}; + +enum{ + FM_TX_RTC_CTRL_DISABLE, + FM_TX_RTC_CTRL_ENABLE, + FM_TX_RTC_CTRL_MAX +}; + +enum{ + FM_TX_DESENSE_DISABLE, + FM_TX_DESENSE_ENABLE, + FM_TX_DESENSE_MAX +}; + +enum{ + FM_WHOLECHIP_RST_OFF, + FM_WHOLECHIP_RST_START, + FM_WHOLECHIP_RST_END, + FM_WHOLECHIP_RST_MAX +}; + +enum{ + FM_SUBSYS_RST_OFF, + FM_SUBSYS_RST_START, + FM_SUBSYS_RST_END, + FM_SUBSYS_RST_MAX +}; + +#define FM_TIMER_TIMEOUT_DEFAULT 1000 +#define FM_TIMER_TIMEOUT_MIN 1000 +#define FM_TIMER_TIMEOUT_MAX 1000000 + +#define FM_RDS_RST_INVAL_DEFAULT 5 +#define FM_RDS_RST_INVAL_MIN 5 +#define FM_RDS_RST_INVAL_MAX 10000 + +#define FM_TX_PWR_CTRL_INVAL_DEFAULT 10 +#define FM_TX_PWR_CTRL_INVAL_MIN 5 +#define FM_TX_PWR_CTRL_INVAL_MAX 10000 + +#define FM_TX_VCO_OFF_DEFAULT 5 +#define FM_TX_VCO_OFF_MIN 1 +#define FM_TX_VCO_OFF_MAX 10000 + +#define FM_TX_VCO_ON_DEFAULT 100 +#define FM_TX_VCO_ON_MIN 10 +#define FM_TX_VCO_ON_MAX 10000 + +#define FM_TX_RTC_CTRL_INTERVAL 10 + +#define FM_GPS_RTC_AGE_TH 2 +#define FM_GPS_RTC_DRIFT_TH 0 +#define FM_GPS_RTC_TIME_DIFF_TH 10 +#define FM_GPS_RTC_RETRY_CNT 1 +#define FM_GPS_RTC_DRIFT_MAX 5000 +enum{ + FM_GPS_RTC_INFO_OLD = 0, + FM_GPS_RTC_INFO_NEW = 1, + FM_GPS_RTC_INFO_MAX +}; +// MUST sync with FM f/w definitions (eg. sys_fm_6620.h) +/* FM opcode */ +#define FM_STP_TEST_OPCODE (0x00) +#define FSPI_ENABLE_OPCODE (0x01) +#define FSPI_MUX_SEL_OPCODE (0x02) +#define FSPI_READ_OPCODE (0x03) +#define FSPI_WRITE_OPCODE (0x04) +#define FI2C_READ_OPCODE (0x05) +#define FI2C_WRITE_OPCODE (0x06) +#define FM_ENABLE_OPCODE (0x07) +#define FM_RESET_OPCODE (0x08) +#define FM_TUNE_OPCODE (0x09) +#define FM_SEEK_OPCODE (0x0a) +#define FM_SCAN_OPCODE (0x0b) +#define RDS_RX_ENABLE_OPCODE (0x0c) +#define RDS_RX_DATA_OPCODE (0x0d) +#define FM_RAMPDOWN_OPCODE (0x0e) +#define FM_MCUCLK_SEL_OPCODE (0x0f) +#define FM_MODEMCLK_SEL_OPCODE (0x10) +#define RDS_TX_OPCODE (0x11) +#define FM_MAX_OPCODE (0x12) + +#define FM_COM_CMD_BASE 0 +typedef enum{ + FM_COM_CMD_TEST = FM_COM_CMD_BASE + 0, + FM_COM_CMD_SEEK, + FM_COM_CMD_SCAN, + FM_COM_CMD_MAX +}fm_com_cmd_t; + +#define SW_RETRY_CNT (2) +#define SW_RETRY_CNT_MAX (5) +#define SW_WAIT_TIMEOUT_MAX (100) +typedef enum +{ + ERR_SUCCESS = 1000, + ERR_INVALID_BUF, + ERR_INVALID_PARA, + ERR_STP, + ERR_GET_MUTEX, + ERR_FW_NORES, + ERR_RDS_CRC, + ERR_WHOLECHIP_RST, + ERR_SUBSYS_RST, + ERR_MAX +}fm_drv_error_t; + +// FM operation timeout define for error handle +#define TEST_TIMEOUT (3) +#define FSPI_EN_TIMEOUT (3) +#define FSPI_MUXSEL_TIMEOUT (3) +#define FSPI_RD_TIMEOUT (3) +#define FSPI_WR_TIMEOUT (3) +#define I2C_RD_TIMEOUT (3) +#define I2C_WR_TIMEOUT (3) +#define EN_TIMEOUT (5) +#define RST_TIMEOUT (3) +#define TUNE_TIMEOUT (3) +#define SEEK_TIMEOUT (10) +#define SCAN_TIMEOUT (15) //usualy scan will cost 10 seconds +#define RDS_RX_EN_TIMEOUT (3) +#define RDS_DATA_TIMEOUT (100) +#define RAMPDOWN_TIMEOUT (3) +#define MCUCLK_TIMEOUT (3) +#define MODEMCLK_TIMEOUT (3) +#define RDS_TX_TIMEOUT (3) +#define POWERON_TIMEOUT (3) +#define POWEROFF_TIMEOUT (3) +#define SEEK_DONE_TIMEOUT (3) +#define SCAN_DONE_TIMEOUT (3) + + +/* FM basic-operation's opcode */ +#define FM_BOP_BASE (0x80) +#define FM_WRITE_BASIC_OP (FM_BOP_BASE + 0x00) +#define FM_UDELAY_BASIC_OP (FM_BOP_BASE + 0x01) +#define FM_RD_UNTIL_BASIC_OP (FM_BOP_BASE + 0x02) +#define FM_MODIFY_BASIC_OP (FM_BOP_BASE + 0x03) +#define FM_MSLEEP_BASIC_OP (FM_BOP_BASE + 0x04) +#define FM_MAX_BASIC_OP (FM_BOP_BASE + 0x05) + +/* FM BOP's size */ +#define FM_WRITE_BASIC_OP_SIZE (3) +#define FM_UDELAY_BASIC_OP_SIZE (4) +#define FM_RD_UNTIL_BASIC_OP_SIZE (5) +#define FM_MODIFY_BASIC_OP_SIZE (5) +#define FM_MSLEEP_BASIC_OP_SIZE (4) + +#define RX_BUF_SIZE 128 +#define TX_BUF_SIZE 1024 + +typedef enum +{ + FM_TASK_RX_PARSER_PKT_TYPE = 0, + FM_TASK_RX_PARSER_OPCODE, + FM_TASK_RX_PARSER_PKT_LEN_1, + FM_TASK_RX_PARSER_PKT_LEN_2, + FM_TASK_RX_PARSER_PKT_PAYLOAD, + FM_TASK_RX_PARSER_BUFFER_CONGESTION +} fm_task_parser_state; + +#define FM_ADDR_RSSI (0xE8) //D9~D0 10bits +#define FM_ADDR_PAMD (0xE9) //D7~D0 8bits +#define FM_ADDR_MR (0xF2) //D8~D0 9bits + +#define FM_TXSCAN_RSSI_TH (-250) +#define FM_TXSCAN_PAMD_TH (-20) +#define FM_TXSCAN_MR_TH (-38) + +#define SCAN_UP (0) +#define SCAN_DOWN (1) + +#define MT6620_SCANTBL_SIZE 16 //16*uinit16_t + +#define FM_TASK_COMMAND_PKT_TYPE 0x01 +#define FM_TASK_EVENT_PKT_TYPE 0x04 + +#define MT6620_FM_SEEK_UP 0x0 +#define MT6620_FM_SEEK_DOWN 0x01 +#define MT6620_FM_SCAN_UP 0x0 +#define MT6620_FM_SCAN_DOWN 0x01 +#define MT6620_FM_SPACE_INVALID 0x0 +#define MT6620_FM_SPACE_50K 0x01 +#define MT6620_FM_SPACE_100K 0x02 +#define MT6620_FM_SPACE_200K 0x04 + +#define FLAG_TEST (1 << 0) +#define FLAG_FSPI_EN (1 << 1) +#define FLAG_FSPI_MUXSEL (1 << 2) +#define FLAG_FSPI_RD (1 << 3) +#define FLAG_FSPI_WR (1 << 4) +#define FLAG_I2C_RD (1 << 5) +#define FLAG_I2C_WR (1 << 6) +#define FLAG_EN (1 << 7) +#define FLAG_RST (1 << 8) +#define FLAG_TUNE (1 << 9) +#define FLAG_SEEK (1 << 10) +#define FLAG_SCAN (1 << 11) +#define FLAG_RDS_RX_EN (1 << 12) +#define FLAG_RDS_DATA (1 << 13) +#define FLAG_RAMPDOWN (1 << 14) +#define FLAG_MCUCLK (1 << 15) +#define FLAG_MODEMCLK (1 << 16) +#define FLAG_RDS_TX (1 << 17) +#define FLAG_OP_MAX (1 << 18) +#define FLAG_POWERON (1 << 19) +#define FLAG_POWEROFF (1 << 20) +#define FLAG_SEEK_DONE (1 << 21) +#define FLAG_SCAN_DONE (1 << 22) +#define FLAG_TERMINATE (1 << 31) + +#endif //__MT6620_FM_H__ diff --git a/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.c b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.c new file mode 100755 index 000000000000..b1d92e6521f7 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.c @@ -0,0 +1,1486 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#include +#include +#include "fm.h" +#include "mt6620_fm.h" +#include "mt6620_fm_lib.h" + +//#define MT6620E1 +//#define MT6620_FM_USE_SHORT_ANTENNA + +int fm_bop_write(uint8_t addr, uint16_t value, unsigned char *buf, int size) +{ + if(size < (FM_WRITE_BASIC_OP_SIZE+2)){ + return (-1); + } + + if(buf == NULL){ + return (-2); + } + + buf[0] = FM_WRITE_BASIC_OP; + buf[1] = FM_WRITE_BASIC_OP_SIZE; + buf[2] = addr; + buf[3] = (uint8_t)((value) & 0x00FF); + buf[4] = (uint8_t)((value >> 8) & 0x00FF); + + FM_LOG_DBG(D_MAIN,"%02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4]); + + return (FM_WRITE_BASIC_OP_SIZE+2); +} + +int fm_bop_udelay(uint32_t value, unsigned char *buf, int size) +{ + if(size < (FM_UDELAY_BASIC_OP_SIZE+2)){ + return (-1); + } + + if(buf == NULL){ + return (-2); + } + + buf[0] = FM_UDELAY_BASIC_OP; + buf[1] = FM_UDELAY_BASIC_OP_SIZE; + buf[2] = (uint8_t)((value) & 0x000000FF); + buf[3] = (uint8_t)((value >> 8) & 0x000000FF); + buf[4] = (uint8_t)((value >> 16) & 0x000000FF); + buf[5] = (uint8_t)((value >> 24) & 0x000000FF); + + FM_LOG_DBG(D_MAIN,"%02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + + return (FM_UDELAY_BASIC_OP_SIZE+2); +} + +int fm_bop_rd_until(uint8_t addr, uint16_t mask, uint16_t value, unsigned char *buf, int size) +{ + if(size < (FM_RD_UNTIL_BASIC_OP_SIZE+2)){ + return (-1); + } + + if(buf == NULL){ + return (-2); + } + + buf[0] = FM_RD_UNTIL_BASIC_OP; + buf[1] = FM_RD_UNTIL_BASIC_OP_SIZE; + buf[2] = addr; + buf[3] = (uint8_t)((mask) & 0x00FF); + buf[4] = (uint8_t)((mask >> 8) & 0x00FF); + buf[5] = (uint8_t)((value) & 0x00FF); + buf[6] = (uint8_t)((value >> 8) & 0x00FF); + + FM_LOG_DBG(D_MAIN,"%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + + return (FM_RD_UNTIL_BASIC_OP_SIZE+2); +} + +int fm_bop_modify(uint8_t addr, uint16_t mask_and, uint16_t mask_or, unsigned char *buf, int size) +{ + if(size < (FM_MODIFY_BASIC_OP_SIZE+2)){ + return (-1); + } + + if(buf == NULL){ + return (-2); + } + + buf[0] = FM_MODIFY_BASIC_OP; + buf[1] = FM_MODIFY_BASIC_OP_SIZE; + buf[2] = addr; + buf[3] = (uint8_t)((mask_and) & 0x00FF); + buf[4] = (uint8_t)((mask_and >> 8) & 0x00FF); + buf[5] = (uint8_t)((mask_or) & 0x00FF); + buf[6] = (uint8_t)((mask_or >> 8) & 0x00FF); + + FM_LOG_DBG(D_MAIN,"%02x %02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); + + return (FM_MODIFY_BASIC_OP_SIZE+2); +} + +int fm_bop_msleep(uint32_t value, unsigned char *buf, int size) +{ + if(size < (FM_MSLEEP_BASIC_OP_SIZE+2)){ + return (-1); + } + + if(buf == NULL){ + return (-2); + } + + buf[0] = FM_MSLEEP_BASIC_OP; + buf[1] = FM_MSLEEP_BASIC_OP_SIZE; + buf[2] = (uint8_t)((value) & 0x000000FF); + buf[3] = (uint8_t)((value >> 8) & 0x000000FF); + buf[4] = (uint8_t)((value >> 16) & 0x000000FF); + buf[5] = (uint8_t)((value >> 24) & 0x000000FF); + + FM_LOG_DBG(D_MAIN,"%02x %02x %02x %02x %02x %02x \n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + + return (FM_MSLEEP_BASIC_OP_SIZE+2); +} + +//MT6620 IC +int mt6620_off_2_longANA(unsigned char *tx_buf, int tx_buf_size) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + pkt_size = 4; + + //A01 Turn on the bandgap and central biasing core + pkt_size += fm_bop_write(0x01, 0x4A00, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 4A00 + pkt_size += fm_bop_udelay(30, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 30 + pkt_size += fm_bop_write(0x01, 0x6A00, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 6A00 + pkt_size += fm_bop_udelay(50, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 50 + //A02 Initialise the LDO's Output + pkt_size += fm_bop_write(0x02, 0x299C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2 299C + //A03 Enable RX, ADC and ADPLL LDO + pkt_size += fm_bop_write(0x01, 0x6B82, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 6B82 + //A04 Update FMRF optimized register settings + pkt_size += fm_bop_write(0x04, 0x0142, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 4 0142 + pkt_size += fm_bop_write(0x05, 0x00E7, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 5 00E7 + pkt_size += fm_bop_write(0x0A, 0x0060, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a 0060 + pkt_size += fm_bop_write(0x0C, 0xA88C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c A88C + pkt_size += fm_bop_write(0x0D, 0x0888, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d 0888 + pkt_size += fm_bop_write(0x10, 0x1E8D, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 10 1E8D + pkt_size += fm_bop_write(0x27, 0x0005, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 27 0005 + pkt_size += fm_bop_write(0x0E, 0x0040, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e 0040 + pkt_size += fm_bop_write(0x03, 0x50F0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3 50f0 + pkt_size += fm_bop_write(0x3F, 0xAD06, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3f AD06 + pkt_size += fm_bop_write(0x3E, 0x3280, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3e 3280 + pkt_size += fm_bop_write(0x06, 0x0124, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6 0124 + pkt_size += fm_bop_write(0x08, 0x15B8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 8 15B8 + //A05 Enable RX related blocks + pkt_size += fm_bop_write(0x28, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 28 0000 + pkt_size += fm_bop_write(0x00, 0x0166, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 0166 + pkt_size += fm_bop_write(0x3A, 0x0004, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3a 0004 + pkt_size += fm_bop_write(0x37, 0x2590, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 37 2590 + // FM ADPLL Power Up + // () for 16.384M mode, otherwise 15.36M + pkt_size += fm_bop_write(0x25, 0x040F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 25 040f + pkt_size += fm_bop_write(0x20, 0x2720, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 20 2720 + //XHC, 2011/03/18, [wr 22 9980->6680] + pkt_size += fm_bop_write(0x22, 0x6680, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 22 9980 + pkt_size += fm_bop_write(0x25, 0x080F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 25 080f + pkt_size += fm_bop_write(0x1E, 0x0863, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1e 0863(0A63) + pkt_size += fm_bop_udelay(5000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 5000 + pkt_size += fm_bop_write(0x1E, 0x0865, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1e 0865 (0A65) + pkt_size += fm_bop_udelay(5000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 5000 + pkt_size += fm_bop_write(0x1E, 0x0871, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1e 0871 (0A71) + pkt_size += fm_bop_udelay(100000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 100000 + pkt_size += fm_bop_write(0x2A, 0x1026, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2a 1026 + // FM RC Calibration + pkt_size += fm_bop_write(0x00, 0x01E6, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 01E6 + pkt_size += fm_bop_udelay(1, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1 + pkt_size += fm_bop_write(0x1B, 0x0094, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1b 0094 + pkt_size += fm_bop_write(0x1B, 0x0095, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1b 0095 + pkt_size += fm_bop_udelay(200, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 200 + pkt_size += fm_bop_write(0x1B, 0x0094, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1b 0094 + pkt_size += fm_bop_write(0x00, 0x0166, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 0166 + // FM VCO Enable + pkt_size += fm_bop_write(0x01, 0x6B8A, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 6B8A + pkt_size += fm_bop_udelay(1, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1 + pkt_size += fm_bop_write(0x00, 0xC166, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 C166 + pkt_size += fm_bop_udelay(3000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 3000 + pkt_size += fm_bop_write(0x00, 0xF166, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 F166 + pkt_size += fm_bop_write(0x09, 0x2964, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9 2964 + // FM RFDIG settings + pkt_size += fm_bop_write(0x2E, 0x0008, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2e 8 + pkt_size += fm_bop_write(0x2B, 0x0064, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2b 64 + pkt_size += fm_bop_write(0x2C, 0x0032, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2c 32 + pkt_size += fm_bop_write(0x11, 0x17d4, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 11 17d4 + //Update dynamic subband switching setting, XHC 2011/05/17 + pkt_size += fm_bop_write(0x13, 0xFA00, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 13 FA00 + pkt_size += fm_bop_write(0x14, 0x0580, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 14 0580 + pkt_size += fm_bop_write(0x15, 0xFA80, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 15 FA80 + pkt_size += fm_bop_write(0x16, 0x0580, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 16 0580 + pkt_size += fm_bop_write(0x33, 0x0008, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 33 0008 + // FM DCOC Calibration + pkt_size += fm_bop_write(0x64, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 64 1 + pkt_size += fm_bop_write(0x63, 0x0020, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 63 20 + pkt_size += fm_bop_write(0x9C, 0x0044, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9C 0044 + //pkt_size += fm_bop_write(0x6B, 0x0100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//"Disable other interrupts except for STC_DONE(dependent on interrupt output source selection)" + pkt_size += fm_bop_write(0x0F, 0x1A08, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr F 1A08 + pkt_size += fm_bop_write(0x63, 0x0021, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 63 21 + pkt_size += fm_bop_rd_until(0x69, 0x0001, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Poll fm_intr_stc_done (69H D0) = 1 + pkt_size += fm_bop_write(0x69, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 69 1 + pkt_size += fm_bop_write(0x63, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 63 0 + pkt_size += fm_bop_rd_until(0x6F, 0x0001, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Poll stc_done (6FH D0)= 0 + // Others + pkt_size += fm_bop_write(0x00, 0xF167, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 F167 + pkt_size += fm_bop_udelay(50000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 50000 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_off_2_longANA_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +int mt6620_rx_digital_init(unsigned char *tx_buf, int tx_buf_size) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + pkt_size = 4; + + // fm_rgf_maincon + //rd 62 + pkt_size += fm_bop_write(0x65, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 65 0 + pkt_size += fm_bop_write(0x64, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 64 1 + pkt_size += fm_bop_write(0x63, 0x0480, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 63 480 + pkt_size += fm_bop_write(0x6D, 0x1AB2, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6d 1ab2 + pkt_size += fm_bop_write(0x6B, 0x2100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6b 2100 + pkt_size += fm_bop_write(0x68, 0xE100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 68 E100 + pkt_size += fm_bop_udelay(10000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 10000 + pkt_size += fm_bop_write(0x68, 0xE000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 68 E000 + // fm_rgf_dac + pkt_size += fm_bop_write(0x9C, 0xab48, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9c ab48 + pkt_size += fm_bop_write(0x9E, 0x000C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9e c + pkt_size += fm_bop_write(0x71, 0x807f, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 71 807f + pkt_size += fm_bop_write(0x72, 0x878f, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 72 878f + //XHC, 2011/04/29 update 0x73 form 0x07C3 to 0x07C1 speed up I/Q calibration + pkt_size += fm_bop_write(0x73, 0x07c1, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 73 7c3 + // fm_rgf_front + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 0 + pkt_size += fm_bop_write(0xCB, 0x00B0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr cb b0 + //XHC, 2011/05/06 FM RSSI config + pkt_size += fm_bop_write(0xE0, ((0xA301 & 0xFC00) | (FMR_RSSI_TH_LONG & 0x03FF)), &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e0 a301 + pkt_size += fm_bop_write(0xE1, ((0x00E9 & 0xFF00) | (FMR_CQI_TH & 0x00FF)), &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e1 D0~D7, PAMD TH + //XHC, 2011/04/15 update search MR threshold + pkt_size += fm_bop_write(0xE3, FMR_MR_TH, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e3 1B0 + pkt_size += fm_bop_write(0xE4, 0x008F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e4 8f + pkt_size += fm_bop_write(0xCC, 0x0488, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr cc 488 + pkt_size += fm_bop_write(0xD6, 0x036A, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d6 36a + pkt_size += fm_bop_write(0xD7, 0x836a, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d7 836a + pkt_size += fm_bop_write(0xDD, 0x0080, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr dd 80 + pkt_size += fm_bop_write(0xB0, 0xcd00, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b0 cd00 + //XHC, 2011/03/18 Update AFC gain[wr 96 41E2->4000][wr 97 049A->021F] + //[wr 98 0B66->0D00][wr 99 0E1E->0E7F][wr D0 8233->8192][wr D1 20BC->2086] + //[wr 90 03FF->0192][wr 91 01BE->0086][wr 92 03FF->0192][wr 93 0354->0086] + //[wr 94 03FF->0192][wr 95 0354->0086][wr 52 17F3] + pkt_size += fm_bop_write(0x96, 0x4000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 96 41E2 + pkt_size += fm_bop_write(0x97, 0x021F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 97 049A + pkt_size += fm_bop_write(0x98, 0x0D00, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 98 0B66 + pkt_size += fm_bop_write(0x99, 0x0E7F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 99 0E1E + pkt_size += fm_bop_write(0xD0, 0x8192, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr D0 8233 + pkt_size += fm_bop_write(0xD1, 0x2086, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr D1 20BC + pkt_size += fm_bop_write(0x90, 0x0192, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 90 03ff + pkt_size += fm_bop_write(0x91, 0x0086, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 91 01BE + pkt_size += fm_bop_write(0x92, 0x0192, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 92 03FF + pkt_size += fm_bop_write(0x93, 0x0086, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 93 0354 + pkt_size += fm_bop_write(0x94, 0x0192, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 94 03FF + pkt_size += fm_bop_write(0x95, 0x0086, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 95 0354 + pkt_size += fm_bop_write(0x52, 0x17F3, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 95 0354 + // fm_rgf_fmx + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 1 + pkt_size += fm_bop_write(0xDE, 0x3388, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr de 3388 + pkt_size += fm_bop_write(0xC2, 0x0180, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c2 180 + pkt_size += fm_bop_write(0xC3, 0x0180, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c3 180 + pkt_size += fm_bop_write(0xDB, 0x0181, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr db 181 + pkt_size += fm_bop_write(0xDC, 0x0184, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr dc 184 + pkt_size += fm_bop_write(0xA2, 0x03C0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a2 3c0 + pkt_size += fm_bop_write(0xA3, 0x03C0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a3 3c0 + pkt_size += fm_bop_write(0xA4, 0x03C0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a4 3c0 + pkt_size += fm_bop_write(0xA5, 0x03C0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a5 3c0 + pkt_size += fm_bop_write(0xA6, 0x03C0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a6 3c0 + pkt_size += fm_bop_write(0xA7, 0x03C0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a7 3c0 + pkt_size += fm_bop_write(0xE3, 0x0280, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e3 280 + pkt_size += fm_bop_write(0xE4, 0x0280, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e4 280 + pkt_size += fm_bop_write(0xE5, 0x0280, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e5 280 + pkt_size += fm_bop_write(0xE6, 0x026C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e6 26c + pkt_size += fm_bop_write(0xE7, 0x026C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr e7 26c + pkt_size += fm_bop_write(0xEA, 0x026C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ea 26c + pkt_size += fm_bop_udelay(1000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000 + pkt_size += fm_bop_write(0xB6, 0x03FC, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b6 3fc + pkt_size += fm_bop_write(0xB7, 0x02C1, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b7 2c1 + pkt_size += fm_bop_write(0xA8, 0x0820, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 820 + pkt_size += fm_bop_write(0xAC, 0x065E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ac 65e + pkt_size += fm_bop_write(0xAD, 0x09AD, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ad 9ad + pkt_size += fm_bop_write(0xAE, 0x0CF8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ae cf8 + pkt_size += fm_bop_write(0xAF, 0x0302, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr af 302 + pkt_size += fm_bop_write(0xB0, 0x04A6, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b0 4a6 + pkt_size += fm_bop_write(0xB1, 0x062C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b1 62c + pkt_size += fm_bop_write(0xEC, 0x014A, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ec 14a + pkt_size += fm_bop_write(0xC8, 0x0232, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c8 232 + pkt_size += fm_bop_write(0xC7, 0x0184, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c7 0184 + pkt_size += fm_bop_write(0xD8, 0x00E8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d8 0e8 + pkt_size += fm_bop_write(0xFB, 0x051F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr fb 51f + pkt_size += fm_bop_udelay(1000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000 + //XHC,2011/03/18 [wr C9 01F0][wr CA 0250][wr D4 2657] + pkt_size += fm_bop_write(0xC9, 0x01F0, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_write(0xCA, 0x0250, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_write(0xD4, 0x2657, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_write(0x9F, 0x0002, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 2 + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0xFF80, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff80 + pkt_size += fm_bop_write(0xA8, 0x0061, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 61 + pkt_size += fm_bop_write(0xA8, 0xFF22, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff22 + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0x0100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 100 + pkt_size += fm_bop_write(0xA8, 0x009A, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 9a + pkt_size += fm_bop_write(0xA8, 0xFF80, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff80 + pkt_size += fm_bop_write(0xA8, 0x0140, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 140 + pkt_size += fm_bop_write(0xA8, 0xFF42, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff42 + pkt_size += fm_bop_write(0xA8, 0xFFE0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ffe0 + pkt_size += fm_bop_write(0xA8, 0x0114, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 114 + pkt_size += fm_bop_write(0xA8, 0xFF4E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff4e + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0x003E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 3e + pkt_size += fm_bop_write(0xA8, 0xFF6E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff6e + pkt_size += fm_bop_write(0xA8, 0x0087, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 87 + pkt_size += fm_bop_write(0xA8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 0 + pkt_size += fm_bop_write(0xA8, 0xFEDC, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 fedc + pkt_size += fm_bop_write(0xA8, 0x0015, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 15 + pkt_size += fm_bop_write(0xA8, 0x00CF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 cf + pkt_size += fm_bop_write(0xA8, 0xFF6B, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff6b + pkt_size += fm_bop_write(0xA8, 0x0164, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 164 + pkt_size += fm_bop_write(0xA8, 0x002B, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 2b + pkt_size += fm_bop_write(0xA8, 0xFF7E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 ff7e + pkt_size += fm_bop_write(0xA8, 0x0065, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a8 65 + pkt_size += fm_bop_udelay(10000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 10000 + pkt_size += fm_bop_write(0x9F, 0x0002, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 2 + pkt_size += fm_bop_write(0xA9, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 0 + pkt_size += fm_bop_write(0xA9, 0xFFEE, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 ffee + pkt_size += fm_bop_write(0xA9, 0xFF81, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 ff81 + //XHC,2011/03/18 [wr A9 FFC3] + pkt_size += fm_bop_write(0xA9, 0xFFC3, &tx_buf[pkt_size], tx_buf_size - pkt_size); + pkt_size += fm_bop_write(0xA9, 0x0022, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 22 + pkt_size += fm_bop_write(0xA9, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 0 + pkt_size += fm_bop_write(0xA9, 0xFFCC, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 ffcc + pkt_size += fm_bop_write(0xA9, 0x0023, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 23 + pkt_size += fm_bop_write(0xA9, 0xFFDA, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 ffda + pkt_size += fm_bop_write(0xA9, 0xFFF7, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a9 fff7 + pkt_size += fm_bop_udelay(10, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 10 + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 1 + pkt_size += fm_bop_write(0xD3, 0x250b, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d3 250b + pkt_size += fm_bop_write(0xBB, 0x2320, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr bb 2320 + pkt_size += fm_bop_write(0xD0, 0x02f8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d0 02f8 + pkt_size += fm_bop_write(0xEC, 0x019a, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ec 19a + pkt_size += fm_bop_write(0xFE, 0x2140, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr fe 2140 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 0 + // fm_rgf_rds + pkt_size += fm_bop_write(0x9F, 0x0003, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 3 + pkt_size += fm_bop_write(0xBD, 0x37EB, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr bd 37eb + pkt_size += fm_bop_write(0xBC, 0x0808, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr bc 808 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_rx_digital_init_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +// TBD for IC +int mt6620_powerdown(unsigned char *tx_buf, int tx_buf_size) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + pkt_size = 4; + +//Digital Modem Power Down + pkt_size += fm_bop_write(0x63, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 63 0 + pkt_size += fm_bop_modify(0x6E, 0xFFFC, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// clear 0x6e[1:0], round1 + pkt_size += fm_bop_modify(0x6E, 0xFFFC, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// clear 0x6e[1:0], round2 + pkt_size += fm_bop_modify(0x6E, 0xFFFC, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// clear 0x6e[1:0], round3 + pkt_size += fm_bop_modify(0x6E, 0xFFFC, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// clear 0x6e[1:0], round4 +//ADPLL Power Off Sequence + pkt_size += fm_bop_write(0x2A, 0x0022, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2a 22 + pkt_size += fm_bop_write(0x1E, 0x0860, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1E 0860 + pkt_size += fm_bop_write(0x20, 0x0720, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 20 0720 + pkt_size += fm_bop_write(0x20, 0x2720, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 20 2720 +//ANALOG/RF Power Off Sequence + pkt_size += fm_bop_write(0x00, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 0 + pkt_size += fm_bop_write(0x01, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 0 + pkt_size += fm_bop_write(0x04, 0x0141, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 4 0141 + pkt_size += fm_bop_write(0x09, 0x0964, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9 0964 + pkt_size += fm_bop_write(0x0C, 0x288C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c 288c + pkt_size += fm_bop_write(0x26, 0x0004, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 0004 + pkt_size += fm_bop_write(0x3A, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3A 0000 + pkt_size += fm_bop_write(0x3B, 0x00C3, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3B 00C3 + pkt_size += fm_bop_write(0x3E, 0x3280, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3E 3280 + pkt_size += fm_bop_write(0x3F, 0x4E16, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3F 4E16 + pkt_size += fm_bop_write(0x41, 0x0004, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 41 0004 + //clear TX settings + pkt_size += fm_bop_write(0x12, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 12 0000 + pkt_size += fm_bop_write(0x47, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 47 0000 + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_powerdown_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +int mt6620_rampdown(unsigned char *tx_buf, int tx_buf_size) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_RAMPDOWN_OPCODE; + pkt_size = 4; + + //XHC, 2011/04/06 ramp 125ms -> 34ms + pkt_size += fm_bop_modify(0x9C, 0xFF87, 0x0068, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9c[3] = 1, ramp down + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 1 + pkt_size += fm_bop_write(0xC8, 0x0101, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c8 101 + pkt_size += fm_bop_write(0xDD, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr dd 0 + pkt_size += fm_bop_write(0xD8, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d8 0 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 0 + pkt_size += fm_bop_udelay(35000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 35000 + //disable interrupt before rampdown + pkt_size += fm_bop_write(0x6B, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6b 0000 + pkt_size += fm_bop_modify(0x63, 0xFFF0, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 63[3:0] = 0, ramp down + pkt_size += fm_bop_rd_until(0x6f, 0x0001, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Poll 6f[0] = b'0 + pkt_size += fm_bop_write(0x6B, 0x2100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6b 2100 + //enable interrupt after rampdown + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_rampdown_tx(unsigned char *tx_buf, int tx_buf_size) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_RAMPDOWN_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_write(0x3B, 0x0500, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3b 0500 + pkt_size += fm_bop_write(0x3A, 0x00FF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3a ff + pkt_size += fm_bop_write(0x65, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 65 1 + pkt_size += fm_bop_write(0x48, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 48 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_rampdown_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_RAMPDOWN_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +// freq: 760 ~ 1080, 100KHz unit, step 1 +int mt6620_tune_1(unsigned char *tx_buf, int tx_buf_size, uint16_t freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + freq = (freq - 640) * 2; + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_TUNE_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_modify(0x0F, 0xFC00, freq, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x0F[9:0] = 0x029e, => ((97.5 - 64) * 20) + pkt_size += fm_bop_modify(0x63, 0xFFFF, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x63[0] = 1 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +// freq: 760 ~ 1080, 100KHz unit, step 2 +int mt6620_tune_2(unsigned char *tx_buf, int tx_buf_size, uint16_t freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + freq = (freq - 640) * 2; + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_TUNE_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_modify(0x9C, 0xFFF7, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x9C[3] = 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +// freq: 760 ~ 1080, 100KHz unit, step 3 +int mt6620_tune_3(unsigned char *tx_buf, int tx_buf_size, uint16_t freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + freq = (freq - 640) * 2; + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_TUNE_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 1 + pkt_size += fm_bop_write(0xC8, 0x0232, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr C8 232 + pkt_size += fm_bop_write(0xDD, 0x8833, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr DD 8833 + pkt_size += fm_bop_write(0xD8, 0x00E8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr D8 E8 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_fast_tune(unsigned char *tx_buf, int tx_buf_size, uint16_t freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + freq = (freq - 640) * 2; + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_TUNE_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_modify(0x63, 0xFFF0, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x63[3:0] = 0 + pkt_size += fm_bop_modify(0x6F, 0xFFFE, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x6F[0] = 0 + pkt_size += fm_bop_modify(0x0F, 0xFC00, freq, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x0F[9:0] = 0x029e, => ((97.5 - 64) * 20) + //disable interrupt before rampdown + pkt_size += fm_bop_write(0x6B, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6b 0000 + pkt_size += fm_bop_modify(0x63, 0xFFFE, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x63[0] = 1 + pkt_size += fm_bop_rd_until(0x69, 0x0001, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Poll 69[0] = b'1 + pkt_size += fm_bop_modify(0x69, 0xFFFE, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x69[0] = 1 + pkt_size += fm_bop_write(0x6B, 0x2100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6b 2100 + //enable interrupt after rampdown + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +// freq: 760 ~ 1080, 100KHz unit +int mt6620_tune_tx(unsigned char *tx_buf, int tx_buf_size, uint16_t freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + freq = (freq - 640) * 2; + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_TUNE_OPCODE; + pkt_size = 4; + + //XHC, 2011/04/20, ramp down before tune + pkt_size += fm_bop_write(0x3B, 0x0500, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3b 0500 + pkt_size += fm_bop_write(0x3A, 0x00FF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3a ff + pkt_size += fm_bop_write(0x65, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 65 1 + pkt_size += fm_bop_write(0x48, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 48 0 + //XHC, 2011/04/14 + pkt_size += fm_bop_modify(0x41, 0xFFFE, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x41[0] = 1 + //XHC, 2011/04/18 + pkt_size += fm_bop_modify(0x12, 0x7FFF, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x12[15] = 0 + //XHC, 2011/04/22, clear RTC compensation info + pkt_size += fm_bop_modify(0x47, 0x003F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x47[15:6] = 0 + pkt_size += fm_bop_modify(0x0F, 0xFC00, freq, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x0F[9:0] = freq + pkt_size += fm_bop_write(0x26, 0x002C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 002C --> SCAL Related --> SCAL_EN and SCAL_GM_EN + pkt_size += fm_bop_udelay(1000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000us + pkt_size += fm_bop_write(0x26, 0x003C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 003C --> SCAL_BUF_EN + pkt_size += fm_bop_udelay(1000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000us + pkt_size += fm_bop_write(0x10, 0x1E8D, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 10 1e8d + pkt_size += fm_bop_udelay(1000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000us + pkt_size += fm_bop_write(0x10, 0x9E8D, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 10 9e8d + pkt_size += fm_bop_udelay(10000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 10000us + pkt_size += fm_bop_write(0x26, 0x0024, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 0024 --> Turn off SCAL gm and BUF + pkt_size += fm_bop_write(0x65, 0x400F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 65 400f + pkt_size += fm_bop_write(0x48, 0x8000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 48 8000 + pkt_size += fm_bop_write(0x3B, 0x0420, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3b 0420 + pkt_size += fm_bop_write(0x3A, 0x01FF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3a 1ff + //XHC, 2011/04/14 + //pkt_size += fm_bop_udelay(10000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 10000us + //pkt_size += fm_bop_modify(0x41, 0xFFFE, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x41[0] = 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +// freq: 760 ~ 1080, 100KHz unit +int mt6620_tune_txscan(unsigned char *tx_buf, int tx_buf_size, uint16_t freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + freq = (freq - 640) * 2; + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_TUNE_OPCODE; + pkt_size = 4; + + //rampdown + //disable interrupt before rampdown + pkt_size += fm_bop_write(0x6B, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6b 0000 + pkt_size += fm_bop_modify(0x63, 0xFFF0, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 63[3:0] = 0, ramp down + pkt_size += fm_bop_rd_until(0x6f, 0x0001, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Poll 6f[0] = b'0 + pkt_size += fm_bop_modify(0x9C, 0xFFFF, 0x0008, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9c[3] = 1, ramp down + pkt_size += fm_bop_write(0x6B, 0x2100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 6b 2100 + //enable interrupt after rampdown + + //set desired channel + pkt_size += fm_bop_modify(0x0F, 0xFC00, freq, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set 0x0F[9:0] = 0x029e, => ((97.5 - 64) * 20) + + //only for short antennal tune +#ifdef MT6620_FM_USE_SHORT_ANTENNA + pkt_size += fm_bop_write(0x28, 0x3800, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 28 3800 + pkt_size += fm_bop_write(0x03, 0x90F0, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3 90f0 + pkt_size += fm_bop_write(0x2E, 0x0028, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2e 28 + pkt_size += fm_bop_write(0x2F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2f 0 + pkt_size += fm_bop_write(0x26, 0x003C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 3c + pkt_size += fm_bop_write(0x2E, 0x002C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2e 2c + pkt_size += fm_bop_udelay(10000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wait 10ms + pkt_size += fm_bop_write(0x26, 0x0024, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 24 + pkt_size += fm_bop_write(0x28, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 28 00 +#endif + + //only for E1 +#ifdef MT6620E1 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + pkt_size += fm_bop_write(0xAF, 0x2210, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr AF 2210 +#endif + + //mask STC_DONE interrupt, 6a(D0) 0 + //pkt_size += fm_bop_modify(0x6A, 0xFFFE, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size); + + //enable hardware are controlled tuning sequence + pkt_size += fm_bop_modify(0x63, 0xFFFF, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set rgf_tune (63H D0) =1 + + //check STC_DONE interrupt status flag + //pkt_size += fm_bop_rd_until(0x69, 0x0001, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Poll fm_intr_stc_done (69H D0) = 1 + + //write 1 clear the STC_DONE status flag + //pkt_size += fm_bop_modify(0x69, 0xFFFF, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);// set stc_done (6FH D0) =1 + + //unmask STC_DONE interrupt, 6a(D0) 1 + //pkt_size += fm_bop_modify(0x6A, 0xFFFF, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size); + + //only for E1 +#ifdef MT6620E1 + //pkt_size += fm_bop_write(0xAF, 0x7710, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr AF 7710 +#endif + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_tune_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_TUNE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +// TBD for IC +int mt6620_seek_1(unsigned char *tx_buf, int tx_buf_size, uint16_t seekdir, uint16_t space, uint16_t max_freq, uint16_t min_freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_SEEK_OPCODE; + pkt_size = 4; + + //A1 Program seek direction, 0x66[10]: 0=seek up, 1=seek down + if(seekdir == MT6620_FM_SEEK_UP){ + pkt_size += fm_bop_modify(0x66, 0xFBFF, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//0x66[10] = 0, seek up + }else{ + pkt_size += fm_bop_modify(0x66, 0xFFFF, 0x0400, &tx_buf[pkt_size], tx_buf_size - pkt_size);//0x66[10] = 1, seek down + } + //0x66[11] 0=no wrarp, 1=wrap + pkt_size += fm_bop_modify(0x66, 0xFFFF, 0x0800, &tx_buf[pkt_size], tx_buf_size - pkt_size);//0x66[11] = 1, wrap + //A2 Program scan channel spacing, 0x66[14:12] step 50KHz:001/100KHz:010/200KHz:100 + if(space == MT6620_FM_SPACE_50K){ + pkt_size += fm_bop_modify(0x66, 0x8FFF, 0x1000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=001 + }else if(space == MT6620_FM_SPACE_100K){ + pkt_size += fm_bop_modify(0x66, 0x8FFF, 0x2000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=010 + }else if(space == MT6620_FM_SPACE_200K){ + pkt_size += fm_bop_modify(0x66, 0x8FFF, 0x4000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=100 + } + + //0x66[9:0] freq upper bound + max_freq = (max_freq - 640) * 2; + pkt_size += fm_bop_modify(0x66, 0xFC00, max_freq, &tx_buf[pkt_size], tx_buf_size - pkt_size); + + //0x67[9:0] freq lower bound + min_freq = (min_freq - 640) * 2; + pkt_size += fm_bop_modify(0x67, 0xFC00, min_freq, &tx_buf[pkt_size], tx_buf_size - pkt_size); + //A3 Enable hardware controlled seeking sequence + pkt_size += fm_bop_modify(0x63, 0xFFFF, 0x0002, &tx_buf[pkt_size], tx_buf_size - pkt_size);//0x63[1] = 1 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_seek_2(unsigned char *tx_buf, int tx_buf_size, uint16_t seekdir, uint16_t space, uint16_t max_freq, uint16_t min_freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_SEEK_OPCODE; + pkt_size = 4; + + //A10 Set softmute to normal mode + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 1 + pkt_size += fm_bop_write(0xC8, 0x0232, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr C8 232 + pkt_size += fm_bop_write(0xDD, 0x8833, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr DD 8833 + pkt_size += fm_bop_write(0xD8, 0x00E8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr D8 E8 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_seek_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_SEEK_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +int mt6620_scan_1(unsigned char *tx_buf, int tx_buf_size, uint16_t scandir, uint16_t space, uint16_t max_freq, uint16_t min_freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_SCAN_OPCODE; + pkt_size = 4; + + //A1 Program scan direction, 0x66[10]: 0=seek up, 1=seek down + if(scandir == MT6620_FM_SCAN_UP){ + pkt_size += fm_bop_modify(0x66, 0xFBFF, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x66[10] = 0, seek up + }else{ + pkt_size += fm_bop_modify(0x66, 0xFFFF, 0x0400, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x66[10] = 1, seek down + } + //0x66[11] 0=no wrarp, 1=wrap + pkt_size += fm_bop_modify(0x66, 0xFFFF, 0x0800, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x66[11] = 1, wrap + //A2 Program scan channel spacing, 0x66[14:12] step 50KHz:001/100KHz:010/200KHz:100 + if(space == MT6620_FM_SPACE_50K){ + pkt_size += fm_bop_modify(0x66, 0x8FFF, 0x1000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=001 + }else if(space == MT6620_FM_SPACE_100K){ + pkt_size += fm_bop_modify(0x66, 0x8FFF, 0x2000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=010 + }else if(space == MT6620_FM_SPACE_200K){ + pkt_size += fm_bop_modify(0x66, 0x8FFF, 0x4000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//clear 0x66[14:12] then 0x66[14:12]=100 + } + + //0x66[9:0] freq upper bound + max_freq = (max_freq - 640) * 2; + pkt_size += fm_bop_modify(0x66, 0xFC00, max_freq, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + + //0x67[9:0] freq lower bound + min_freq = (min_freq - 640) * 2; + pkt_size += fm_bop_modify(0x67, 0xFC00, min_freq, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size); + + //A3 Enable hardware controlled scanning sequence + pkt_size += fm_bop_modify(0x63, 0xFFFF, 0x0004, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x63[2] = 1 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_scan_2(unsigned char *tx_buf, int tx_buf_size, uint16_t scandir, uint16_t space, uint16_t max_freq, uint16_t min_freq) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_SCAN_OPCODE; + pkt_size = 4; + + //A10 Set softmute to normal mode + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 1 + pkt_size += fm_bop_write(0xC8, 0x0232, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr C8 232 + pkt_size += fm_bop_write(0xDD, 0x8833, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr DD 8833 + pkt_size += fm_bop_write(0xD8, 0x00E8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr D8 E8 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_com(unsigned char *tx_buf, int tx_buf_size, int opcode, void* data) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; //FM_ENABLE_OPCODE can be used by other user + pkt_size = 4; + + switch(opcode){ + case FM_COM_CMD_TEST: + //disable mute + pkt_size += fm_bop_modify(0x9C, 0xFFF7, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x9c[3] = 0 + break; + case FM_COM_CMD_SCAN: + //A7 Set to read page 1 + pkt_size += fm_bop_modify(0x9F, 0xFFFC, 0x0001, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x9F D0~D1 = 01 + //A8 Read back channel scan bit_map information + //A9 disable mute + pkt_size += fm_bop_modify(0x9C, 0xFFF7, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x9c[3] = 0 + pkt_size += fm_bop_udelay(35000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 35ms + //A10 Set softmute to normal mode + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 1 + pkt_size += fm_bop_write(0xC8, 0x0232, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr C8 232 + pkt_size += fm_bop_write(0xDD, 0x8833, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr DD 8833 + pkt_size += fm_bop_write(0xD8, 0x00E8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr D8 E8 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + break; + case FM_COM_CMD_SEEK: + //A7 Set to read page 1 + pkt_size += fm_bop_modify(0x9F, 0xFFFC, 0x0001, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x9F D0~D1 = 01 + //A8 Read back channel scan bit_map information + //A9 disable mute + pkt_size += fm_bop_modify(0x9C, 0xFFF7, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//0x9c[3] = 0 + pkt_size += fm_bop_udelay(35000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 35ms + //A10 Set softmute to normal mode + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 1 + pkt_size += fm_bop_write(0xC8, 0x0232, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr C8 232 + pkt_size += fm_bop_write(0xDD, 0x8833, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr DD 8833 + pkt_size += fm_bop_write(0xD8, 0x00E8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr D8 E8 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + break; + default: + return -1; + break; + } + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_scan_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_SCAN_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +int mt6620_rds_rx_enable(unsigned char *tx_buf, int tx_buf_size) //IC version +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = RDS_RX_ENABLE_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_write(0x9F, 0x0003, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0x9f 3 + pkt_size += fm_bop_write(0xCB, 0xE016, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Wr 0xcb e016 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0x9f 0 + pkt_size += fm_bop_write(0x63, 0x0491, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Wr 0x63 491 + pkt_size += fm_bop_modify(0x6B, 0xFFFF, 0x2000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//Wr 0x6b [13] = 1 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_rds_rx_enable_ack(unsigned char *tx_buf, int tx_buf_size) //IC version +{ + int pkt_size = 0; + + pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = RDS_RX_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +int mt6620_rds_rx_disable(unsigned char *tx_buf, int tx_buf_size) //IC version +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = RDS_RX_ENABLE_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_modify(0x6B, 0xDFFF, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//Wr 0x6b [13] = 0 + pkt_size += fm_bop_write(0x63, 0x0481, &tx_buf[pkt_size], tx_buf_size - pkt_size);//Wr 0x63 481 + + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_rds_rx_disable_ack(unsigned char *tx_buf, int tx_buf_size) //IC version +{ + int pkt_size = 0; + + pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = RDS_RX_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +// TBD for IC +int mt6620_rds_tx(unsigned char *tx_buf, int tx_buf_size, uint16_t pi, uint16_t *ps, uint16_t *other_rds, uint8_t other_rds_cnt) +{ + int pkt_size = 0; + int i; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + if(other_rds_cnt > 29){ + return (-2); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = RDS_TX_OPCODE; + pkt_size = 4; + + //RDS Tx config + pkt_size += fm_bop_modify(0x65, 0xFFFF, 0x0010, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//wr 65[4] = b'1, enable RDS Tx + pkt_size += fm_bop_write(0x9F, 0x0003, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 3 + pkt_size += fm_bop_write(0xA2, 0x0005, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a2 5, repeat + PI_reg mode + pkt_size += fm_bop_write(0xA1, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a1 0 + //pkt_size += fm_bop_write(0xA0, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a0 1 + pkt_size += fm_bop_write(0xA4, pi, &tx_buf[pkt_size], tx_buf_size - pkt_size);//write PI to PI_reg + //program PS buf + pkt_size += fm_bop_rd_until(0xAA, 0x0001, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);// rd until aa[0] = b'0, ptr in normal buf + //program normal buf, workaround that PS buf can't work while normal buf is empty + for(i = 0; i < 12; i++) + { + pkt_size += fm_bop_write(0xA8, ps[i], &tx_buf[pkt_size], tx_buf_size - pkt_size);//a8 = RDS Tx data + } + pkt_size += fm_bop_modify(0xA2, 0xFFFF, 0x0002, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//wr a2[1] = b'1, mem_addr mode + for(i = 0; i < 12; i++) + { + pkt_size += fm_bop_write(0xA7, (0x0063+i), &tx_buf[pkt_size], tx_buf_size - pkt_size);//a7 = mem_addr + pkt_size += fm_bop_write(0xA8, ps[i], &tx_buf[pkt_size], tx_buf_size - pkt_size);//a8 = RDS Tx data + } + pkt_size += fm_bop_modify(0xA2, 0xFFFF, 0x0010, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//wr a2[4] = b'1, switch to ps buf + //program normal buf + pkt_size += fm_bop_rd_until(0xAA, 0x0001, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);// rd until aa[0] = b'1, ptr in ps buf + pkt_size += fm_bop_modify(0xA2, 0xFFFD, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//wr a2[1] = b'0, h/w addr mode + for(i = 0; i < 12; i++) + { + pkt_size += fm_bop_write(0xA8, ps[i], &tx_buf[pkt_size], tx_buf_size - pkt_size);//a8 = RDS Tx data + } + for(i = 0; i < (other_rds_cnt * 3); i++) + { + pkt_size += fm_bop_write(0xA8, other_rds[i], &tx_buf[pkt_size], tx_buf_size - pkt_size);//a8 = RDS Tx data + } + pkt_size += fm_bop_modify(0xA2, 0xFFEF, 0x0000, &tx_buf[pkt_size], TX_BUF_SIZE - pkt_size);//wr a2[4] = b'0, switch to normal buf + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_rds_tx_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = RDS_TX_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +int mt6620_get_reg(unsigned char *tx_buf, int tx_buf_size, uint8_t addr) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FSPI_READ_OPCODE; + tx_buf[2] = 0x01; + tx_buf[3] = 0x00; + tx_buf[4] = addr; + + return 5; +} + +int mt6620_set_reg(unsigned char *tx_buf, int tx_buf_size, uint8_t addr, uint16_t value) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FSPI_WRITE_OPCODE; + tx_buf[2] = 0x03; + tx_buf[3] = 0x00; + tx_buf[4] = addr; + tx_buf[5] = (uint8_t)((value) & 0x00FF); + tx_buf[6] = (uint8_t)((value >> 8) & 0x00FF); + + return 7; +} + +int mt6620_set_reg_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FSPI_WRITE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +// TBD for IC +int mt6620_off_2_tx_shortANA(unsigned char *tx_buf, int tx_buf_size) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + pkt_size = 4; + + pkt_size += fm_bop_write(0x01, 0x4A00, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 4A00 --> Turn on Central Bias + FC + pkt_size += fm_bop_udelay(30, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 30 + pkt_size += fm_bop_write(0x01, 0x6A00, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 6A00 --> Turn off FC + pkt_size += fm_bop_udelay(50, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 50 + pkt_size += fm_bop_write(0x02, 0x299C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2 299C --> Set the LDOs Output Voltages + pkt_size += fm_bop_write(0x01, 0x6B82, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 6B82 --> Turn on DCO, RX and ADDA LDO + pkt_size += fm_bop_write(0x3B, 0x0500, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3B 0500 --> Turn on PA LDO --> LDO PA = 2.5V [0000 010x xxx0 000] {xxxx} - 0001 = 2.5V + pkt_size += fm_bop_write(0x04, 0x0548, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 4 0548 --> Set the RX LDO to Low Power Mode + TR Switch Off + pkt_size += fm_bop_write(0x37, 0x2000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 37 2000 --> Set the Short Antenna Bias + pkt_size += fm_bop_write(0x42, 0xC002, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 42 C002 --> Set the Short Antenna Bias + pkt_size += fm_bop_write(0x0A, 0x0060, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr A 0060 --> Update AFCDAC LPF Setting + pkt_size += fm_bop_write(0x0E, 0x0040, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr E 0040 --> Update SX_VDC_CBANK + pkt_size += fm_bop_write(0x0C, 0xA88C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c A88C + pkt_size += fm_bop_write(0x10, 0x1E8D, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 10 1e8d + pkt_size += fm_bop_write(0x27, 0x0005, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 27 0005 --> Update ACAL and Enable RMS_DET + pkt_size += fm_bop_write(0x11, 0x07D8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 11 07D8 --> Set VCO_DIVRST_N = 0 + pkt_size += fm_bop_write(0x41, 0x0003, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 41 0003 --> Set TX_FVCO_EN = 1 and FVCO_SEL=1 + pkt_size += fm_bop_write(0x08, 0x25B8, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 8 25b8 --> ADC = TX Mode (AU_ADC) + pkt_size += fm_bop_write(0x09, 0x2964, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9 2964 --> ADC DWA ON + pkt_size += fm_bop_write(0x3F, 0xAD86, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3F AD86 --> TX DAc RX_TX_SEL = TX MOde + pkt_size += fm_bop_write(0x3A, 0x01EF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3A 01EF --> Turn on TX Chain [PA+D2S+HRM+AUPGA+TXDAC+LODIV] + pkt_size += fm_bop_write(0x3E, 0x3181, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3E 3181 --> TX LPF EN + CSEL from RCCAL + pkt_size += fm_bop_write(0x00, 0x0100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 0100 --> Turn on SDADC + pkt_size += fm_bop_write(0x37, 0x2000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 37 2000 --> Control Signal for DAC_CK output clock gate + //FM ADPLL Power Up + pkt_size += fm_bop_write(0x25, 0x040F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 25 040f --> Turn off DIG_CK_EN + pkt_size += fm_bop_write(0x20, 0x2720, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 20 2720 --> Turn on ADPLL 2320 CW32 + //XHC,2011/03/18, [wr 22 9980-> 6680] + pkt_size += fm_bop_write(0x22, 0x6680, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 22 9980 --> Update DLF Gain + pkt_size += fm_bop_write(0x25, 0x080F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 25 080f --> Update I_CODE_CCAL + ADC_CK_EN + 32KCLKPLL_EN 0803 CW37 + pkt_size += fm_bop_write(0x1E, 0x0863, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1e 0863 --> Turn on DCO + CAL_COARSE_EN + pkt_size += fm_bop_udelay(5000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 5000 + pkt_size += fm_bop_write(0x1E, 0x0865, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1e 0865 --> Change the CAL_COARSE to CAL_FINE + pkt_size += fm_bop_udelay(5000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 5000 + pkt_size += fm_bop_write(0x1E, 0x0871, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1e 0871 --> Off the CAL_COARSE and CAL_FINE + Turn on PLL + pkt_size += fm_bop_udelay(100000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 100000 + pkt_size += fm_bop_write(0x2A, 0x1026, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2a 1022 --> Enable TOP_CG + //FM RC Calibration + pkt_size += fm_bop_write(0x00, 0x0080, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 0080 --> RCCAL + pkt_size += fm_bop_udelay(1, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000 + pkt_size += fm_bop_write(0x1B, 0x0094, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1b 0094 --> Update RCCAL Target Count + pkt_size += fm_bop_write(0x1B, 0x0095, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1b 0095 --> Start RCCAL + pkt_size += fm_bop_udelay(200, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000 + pkt_size += fm_bop_write(0x1B, 0x0094, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1b 0094 --> Off RCCAL + pkt_size += fm_bop_write(0x00, 0x0100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 0100 --> Turn off RCCAL Analog Block + //FM VCO Enable + pkt_size += fm_bop_write(0x01, 0x6B8A, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 1 6B8A --> Turn on VCO LDO + pkt_size += fm_bop_udelay(1, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 1000 + pkt_size += fm_bop_write(0x00, 0xC100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 0 C100 --> Turn on VCO, AFCDAC + pkt_size += fm_bop_write(0x0C, 0xB88C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c B88c --> Turn on Const gm + pkt_size += fm_bop_udelay(3000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 3000 + pkt_size += fm_bop_write(0x3A, 0x01FF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3A 01FF --> Enable TX Divider + //Short Antenna Setting + pkt_size += fm_bop_write(0x42, 0xF002, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 42 F002 --> MSB of HRM_Gain <5> ****>> For Max Pout + pkt_size += fm_bop_write(0x3C, 0xABE9, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3C ABE9 --> Max HRM Gain<4:0> - xxxxx [1010 10xx xxx0 1001] + pkt_size += fm_bop_write(0x3D, 0x027E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 3D 027E --> Max PA Gain<4:0> - [0000 0010 0xxx xx10] + pkt_size += fm_bop_write(0x33, 0x0008, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 33 0008 --> Use old VCO calibration routine to save calibration time + pkt_size += fm_bop_write(0x28, 0xFFFF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 28 FFFF + pkt_size += fm_bop_write(0x2E, 0x0020, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2E 0020 --> Turn on SCAL_HWTRIG_DIS --> VCO CAL and SCAL are done separately + pkt_size += fm_bop_write(0x2F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2F 0000 --> Disable Capbank manual enter mode [4A40 previously] + pkt_size += fm_bop_write(0x44, 0x006E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 44 6e + pkt_size += fm_bop_write(0x46, 0xDC22, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 46 DC22 + pkt_size += fm_bop_write(0x49, 0x0080, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 49 80 + pkt_size += fm_bop_write(0x4A, 0x0004, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 4A 4 + pkt_size += fm_bop_write(0x4B, 0x0040, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 4B 40 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_off_2_tx_shortANA_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +// TBD for IC +int mt6620_dig_init(unsigned char *tx_buf, int tx_buf_size) +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + pkt_size = 4; + +//fm_rgf_maincon + pkt_size += fm_bop_write(0x64, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 64 0 + pkt_size += fm_bop_write(0x65, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 65 1 + pkt_size += fm_bop_write(0x68, 0xE100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 68 E100 + pkt_size += fm_bop_udelay(10000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//delay 10000 + pkt_size += fm_bop_write(0x68, 0xE000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 68 E000 +//fm_rgf_dac + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9F 0 + pkt_size += fm_bop_write(0x9E, 0x001C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9E 1C + pkt_size += fm_bop_write(0x9C, 0xA540, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9c A540 +//fm_rgf_front + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 0 --> start rgf_front + pkt_size += fm_bop_write(0xB8, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b8 1 + pkt_size += fm_bop_write(0xAB, 0x39B6, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ab 39b6 + pkt_size += fm_bop_write(0xAC, 0x3C3E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ac 3c3e + pkt_size += fm_bop_write(0xAD, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ad 0 + pkt_size += fm_bop_write(0xAE, 0x03C2, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ae 3c2 + pkt_size += fm_bop_write(0xAF, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr af 1 + pkt_size += fm_bop_write(0xB1, 0x623D, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b1 623d + pkt_size += fm_bop_write(0xF4, 0x0020, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr f4 20 + pkt_size += fm_bop_write(0xF5, 0xBF16, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr f5 bf16 + pkt_size += fm_bop_write(0xB9, 0x0050, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b9 0050 + pkt_size += fm_bop_write(0xBA, 0x00C3, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ba 00c3 + pkt_size += fm_bop_write(0xBB, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr bb 0 + pkt_size += fm_bop_write(0xBC, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr bc 0 + pkt_size += fm_bop_write(0xBD, 0x0056, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr bd 56 + pkt_size += fm_bop_write(0xBE, 0x0089, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr be 89 + pkt_size += fm_bop_write(0xBF, 0x004C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr bf 4c + pkt_size += fm_bop_write(0xC0, 0x0171, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c0 171 + pkt_size += fm_bop_write(0xC1, 0x002B, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c1 2b + pkt_size += fm_bop_write(0xC2, 0x001F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c2 1f + pkt_size += fm_bop_write(0xC3, 0x0066, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c3 66 + pkt_size += fm_bop_write(0xC4, 0x00F6, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c4 f6 + pkt_size += fm_bop_write(0xC5, 0x0066, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c5 66 + pkt_size += fm_bop_write(0xC6, 0x001F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c6 1f + pkt_size += fm_bop_write(0xC7, 0x0007, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c7 7 + pkt_size += fm_bop_write(0xFE, 0x0039, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr fe 39 + pkt_size += fm_bop_write(0xFF, 0x3907, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ff 3907 +//fm_rgf_fmx + pkt_size += fm_bop_write(0x9F, 0x0001, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 1 --> start rgf_outer + pkt_size += fm_bop_write(0xC0, 0x076C, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c0 76c + pkt_size += fm_bop_write(0xB7, 0x0004, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr b7 4 + pkt_size += fm_bop_write(0xD8, 0x006A, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d8 6a + pkt_size += fm_bop_write(0xC8, 0x2828, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c8 2828 + pkt_size += fm_bop_write(0xCE, 0x0090, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ce 90 + pkt_size += fm_bop_write(0xFE, 0x000F, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr fe f + pkt_size += fm_bop_write(0xA2, 0x0100, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a2 100 + pkt_size += fm_bop_write(0xA3, 0x0111, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a3 111 + pkt_size += fm_bop_write(0xA4, 0x0122, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a4 122 + pkt_size += fm_bop_write(0xA5, 0x0135, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a5 135 + pkt_size += fm_bop_write(0xA6, 0x0149, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a6 149 + pkt_size += fm_bop_write(0xA7, 0x015E, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a7 15e + pkt_size += fm_bop_write(0xDB, 0x0174, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr db 174 + pkt_size += fm_bop_write(0xDC, 0x018D, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr dc 18d + pkt_size += fm_bop_write(0xC9, 0x01A6, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr c9 1a6 + pkt_size += fm_bop_write(0xCA, 0x01C1, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr ca 1c1 + pkt_size += fm_bop_write(0xCB, 0x01DE, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr cb 1de + pkt_size += fm_bop_write(0xCC, 0x01FD, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr cc 1fd + pkt_size += fm_bop_write(0xD4, 0x2657, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr d4 2657 + pkt_size += fm_bop_write(0xA0, 0x85B2, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr a0 85b2 + pkt_size += fm_bop_write(0x9F, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 9f 0 + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_dig_init_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + +// TBD for IC +int mt6620_ant_switch(unsigned char *tx_buf, int tx_buf_size, int dir) // dir: 0=long2short / 1=short2long +{ + int pkt_size = 0; + + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_COMMAND_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + pkt_size = 4; + + if(dir == 0){ + // long2short + pkt_size += fm_bop_write(0x04, 0x0145, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 4 0145 + pkt_size += fm_bop_write(0x05, 0x00FF, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 5 00FF + pkt_size += fm_bop_write(0x26, 0x0024, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 0024 + pkt_size += fm_bop_write(0x2E, 0x0000, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2E 0000 + }else{ + // short2long + pkt_size += fm_bop_write(0x04, 0x0142, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 4 0142 + pkt_size += fm_bop_write(0x05, 0x00E7, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 5 00E7 + pkt_size += fm_bop_write(0x26, 0x0004, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 26 0004 + pkt_size += fm_bop_write(0x2E, 0x0008, &tx_buf[pkt_size], tx_buf_size - pkt_size);//wr 2E 0008 + } + + tx_buf[2] = (uint8_t)((pkt_size-4) & 0x00FF); + tx_buf[3] = (uint8_t)(((pkt_size-4) >> 8) & 0x00FF); + + return pkt_size; +} + +int mt6620_ant_switch_ack(unsigned char *tx_buf, int tx_buf_size) +{ + if(tx_buf_size < TX_BUF_SIZE){ + return (-1); + } + + tx_buf[0] = FM_TASK_EVENT_PKT_TYPE; + tx_buf[1] = FM_ENABLE_OPCODE; + tx_buf[2] = 0x00; + tx_buf[3] = 0x00; + + return 4; +} + diff --git a/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.h b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.h new file mode 100755 index 000000000000..17b40d723154 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_lib.h @@ -0,0 +1,94 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#include + +//#define MT6620_FPGA + +#define FM_MAIN_PGSEL (0x9F) +#define FM_MAIN_BASE (0x0) +#define FM_MAIN_BITMAP0 (FM_MAIN_BASE + 0x80) +#define FM_MAIN_BITMAP1 (FM_MAIN_BASE + 0x81) +#define FM_MAIN_BITMAP2 (FM_MAIN_BASE + 0x82) +#define FM_MAIN_BITMAP3 (FM_MAIN_BASE + 0x83) +#define FM_MAIN_BITMAP4 (FM_MAIN_BASE + 0x84) +#define FM_MAIN_BITMAP5 (FM_MAIN_BASE + 0x85) +#define FM_MAIN_BITMAP6 (FM_MAIN_BASE + 0x86) +#define FM_MAIN_BITMAP7 (FM_MAIN_BASE + 0x87) +#define FM_MAIN_BITMAP8 (FM_MAIN_BASE + 0x88) +#define FM_MAIN_BITMAP9 (FM_MAIN_BASE + 0x89) +#define FM_MAIN_BITMAPA (FM_MAIN_BASE + 0x8a) +#define FM_MAIN_BITMAPB (FM_MAIN_BASE + 0x8b) +#define FM_MAIN_BITMAPC (FM_MAIN_BASE + 0x8c) +#define FM_MAIN_BITMAPD (FM_MAIN_BASE + 0x8d) +#define FM_MAIN_BITMAPE (FM_MAIN_BASE + 0x8e) +#define FM_MAIN_BITMAPF (FM_MAIN_BASE + 0x8f) + +int mt6620_off_2_longANA(unsigned char *tx_buf, int tx_buf_size); +int mt6620_off_2_longANA_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rx_digital_init(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rx_digital_init_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_powerdown(unsigned char *tx_buf, int tx_buf_size); +int mt6620_powerdown_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rampdown(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rampdown_tx(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rampdown_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_tune_1(unsigned char *tx_buf, int tx_buf_size, uint16_t freq); +int mt6620_tune_2(unsigned char *tx_buf, int tx_buf_size, uint16_t freq); +int mt6620_tune_3(unsigned char *tx_buf, int tx_buf_size, uint16_t freq); +int mt6620_fast_tune(unsigned char *tx_buf, int tx_buf_size, uint16_t freq); +int mt6620_tune_txscan(unsigned char *tx_buf, int tx_buf_size, uint16_t freq); +int mt6620_tune_tx(unsigned char *tx_buf, int tx_buf_size, uint16_t freq); +int mt6620_tune_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_seek_1(unsigned char *tx_buf, int tx_buf_size, uint16_t seekdir, uint16_t space, uint16_t max_freq, uint16_t min_freq); +int mt6620_seek_2(unsigned char *tx_buf, int tx_buf_size, uint16_t seekdir, uint16_t space, uint16_t max_freq, uint16_t min_freq); +int mt6620_seek_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_scan_1(unsigned char *tx_buf, int tx_buf_size, uint16_t scandir, uint16_t space, uint16_t max_freq, uint16_t min_freq); +int mt6620_scan_2(unsigned char *tx_buf, int tx_buf_size, uint16_t scandir, uint16_t space, uint16_t max_freq, uint16_t min_freq); +int mt6620_scan_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rds_rx_enable(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rds_rx_enable_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rds_rx_disable(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rds_rx_disable_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_rds_tx(unsigned char *tx_buf, int tx_buf_size, uint16_t pi, uint16_t *ps, uint16_t *other_rds, uint8_t other_rds_cnt); +int mt6620_rds_tx_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_get_reg(unsigned char *tx_buf, int tx_buf_size, uint8_t addr); +int mt6620_set_reg(unsigned char *tx_buf, int tx_buf_size, uint8_t addr, uint16_t value); +int mt6620_set_reg_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_off_2_tx_shortANA(unsigned char *tx_buf, int tx_buf_size); +int mt6620_off_2_tx_shortANA_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_dig_init(unsigned char *tx_buf, int tx_buf_size); +int mt6620_dig_init_ack(unsigned char *tx_buf, int tx_buf_size); +int mt6620_com(unsigned char *tx_buf, int tx_buf_size, int opcode, void* data); diff --git a/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_reg.h b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_reg.h new file mode 100755 index 000000000000..2f1e9c3ff3b3 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_fm_reg.h @@ -0,0 +1,65 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#ifndef __MT6620_FM_REG_H__ +#define __MT6620_FM_REG_H__ + +//private chip define +#define MT6620_FM_PGSEL (0x9F) +#define MT6620_FM_RSSI_IND (0xE8) +#define MT6620_FM_PAMD_IND (0xE9) +#define MT6620_FM_MR_IND (0xF2) +#define MT6620_FM_STEROMONO_IND (0xF8) +#define MT6620_FM_STEROMONO_CTR (0xE0) + +//common define +#define FM_PGSEL MT6620_FM_PGSEL +#define FM_RSSI_IND MT6620_FM_RSSI_IND +#define FM_PAMD_IND MT6620_FM_PAMD_IND +#define FM_MR_IND MT6620_FM_MR_IND +#define FM_STEROMONO_IND MT6620_FM_STEROMONO_IND +#define FM_STEROMONO_CTR MT6620_FM_STEROMONO_CTR + +//FM reg page +enum FM_PAGE{ + FM_PG0 = 0, + FM_PG1, + FM_PG2, + FM_PG3, + FM_PGMAX +}; + +#endif //__MT6620_FM_REG_H__ + diff --git a/drivers/mtk_wcn_combo/drv_fm/public/mt6620_rds.c b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_rds.c new file mode 100755 index 000000000000..c848ff57be5b --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_fm/public/mt6620_rds.c @@ -0,0 +1,1878 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + * + * MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +#include +#include +#include +#include // udelay() +#include // device_create() +#include +#include +#include +#include + +#include // get_user() + +#include "fm.h" +#include "mt6620_fm.h" +#include "mt6620_fm_lib.h" + +/****************************************************************************** + * GLOBAL DATA + *****************************************************************************/ +#define MT6620_RDS_BLER_TH1 90 +#define MT6620_RDS_BLER_TH2 60 +#define MT6620_RDS_BLER_C1 12 +#define MT6620_RDS_BLER_C2 6 +#define MT6620_RDS_BLER_T1 5000 +#define MT6620_RDS_BLER_T2 5000 + +//FM_RDS_DATA_CRC_FFOST(0xB2) +#define FM_RDS_GDBK_IND_A (0x08) +#define FM_RDS_GDBK_IND_B (0x04) +#define FM_RDS_GDBK_IND_C (0x02) +#define FM_RDS_GDBK_IND_D (0x01) +#define FM_RDS_DCO_FIFO_OFST (0x01E0) +#define FM_RDS_READ_DELAY (0x80) + + +/****************************************************************************** + * GLOBAL VARIABLE + *****************************************************************************/ +static bool bRDS_FirstIn = false; +static uint16_t RDS_Sync_Cnt = 0, RDS_Block_Reset_Cnt = 0; + +extern int16_t _current_frequency; +uint32_t gBLER_CHK_INTERVAL = 5000; +static int16_t preAF_Num = 0; +static int16_t preAFON_Num = 0; +uint16_t GOOD_BLK_CNT = 0, BAD_BLK_CNT = 0; +uint8_t BAD_BLK_RATIO = 0; + +#ifndef FM_ASSERT +#define FM_ASSERT(a) { \ + if ((a) == NULL) { \ + printk("%s, invalid buf\n", __func__);\ + return -ERR_INVALID_BUF; \ + } \ + } +#endif + +#define RDS_RT_MULTI_REV_TH 16 +enum +{ + RDS_GRP_VER_A = 0, //group version A + RDS_GRP_VER_B +}; + +typedef enum RDS_RT_STATE_MACHINE +{ + RDS_RT_START = 0, + RDS_RT_DECISION, + RDS_RT_GETLEN, + RDS_RT_DISPLAY, + RDS_RT_FINISH, + RDS_RT_MAX +}RDS_RT_STATE_MACHINE; + +typedef enum RDS_BLK_T +{ + RDS_BLK_A = 0, + RDS_BLK_B, + RDS_BLK_C, + RDS_BLK_D, + RDS_BLK_MAX +}RDS_BLK_T; + +static RDS_RT_STATE_MACHINE rt_state_machine = RDS_RT_START; + +/****************************************************************************** + * Local function extern + *****************************************************************************/ +static int MT6620_RDS_enable(void); +static int MT6620_RDS_disable(void); +static int MT6620_RDS_Get_GoodBlock_Counter(uint16_t* pCnt); +static int MT6620_RDS_Get_BadBlock_Counter(uint16_t* pCnt); +static int MT6620_RDS_Reset_Block_Counter(void); +static int MT6620_RDS_Reset(void); +static int MT6620_RDS_Reset_Block(void); +static int MT6620_RDS_Init_Data(RDSData_Struct *pstRDSData); +static int MT6620_RDS_RetrieveGroup0(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData); +static int MT6620_RDS_RetrieveGroup1(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData); +static int MT6620_RDS_RetrieveGroup2(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData); +static int MT6620_RDS_RetrieveGroup4(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData); +static int MT6620_RDS_RetrieveGroup14(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData); +extern int MT6620_read(uint8_t addr, uint16_t *val); +extern int MT6620_write(uint8_t addr, uint16_t val); +extern int MT6620_set_bits(uint8_t addr, uint16_t bits, uint16_t mask); +extern int Delayms(uint32_t data); +extern int Delayus(uint32_t data); + +/* + * rds_cnt_get + * To get rds group count form raw data + * If success return 0, else return error code +*/ +static int rds_cnt_get(struct rds_rx *rds_raw, int raw_size, int *cnt){ + int ret = 0; + int gap = sizeof(rds_raw->cos) + sizeof(rds_raw->sin); + + FM_ASSERT(rds_raw); + FM_ASSERT(cnt); + *cnt = (raw_size - gap)/sizeof(rds_packet_struct); + FM_LOG_INF(D_RDS,"group cnt=%d\n", *cnt); + + return ret; +} + +/* + * rds_group_get + * To get rds group[n] data form raw data with index + * If success return 0, else return error code +*/ +static int rds_group_get(uint16_t *dst, struct rds_rx *raw, int idx){ + int ret = 0; + + FM_ASSERT(dst); + FM_ASSERT(raw); + if(idx > (MAX_RDS_RX_GROUP_CNT - 1)){ + ret = -ERR_INVALID_PARA; + return ret; + } + dst[0] = raw->data[idx].blkA; + dst[1] = raw->data[idx].blkB; + dst[2] = raw->data[idx].blkC; + dst[3] = raw->data[idx].blkD; + dst[4] = raw->data[idx].crc; + dst[5] = raw->data[idx].cbc; + + FM_LOG_INF(D_RDS,"BLOCK:%04x %04x %04x %04x, CRC:%04x\n", dst[0], dst[1], dst[2], dst[3], dst[4]); + + return ret; +} + +/* + * rds_checksum_check + * To check CRC rerult, if OK, *valid=TRUE, else *valid=FALSE + * If success return 0, else return error code +*/ +static int rds_checksum_check(uint16_t crc, int mask, bool *valid){ + int ret = 0; + + FM_ASSERT(valid); + if((crc & mask) == mask){ + *valid = TRUE; + }else{ + *valid = FALSE; + } + + return ret; +} + +/* + * rds_cbc_get - To get block_n's correct bit count form cbc + * @cbc, the group's correct bit count + * @blk, target the block + * + * If success, return block_n's cbc, else error code +*/ +static int rds_cbc_get(uint16_t cbc, enum RDS_BLK_T blk){ + int ret = 0; + + switch(blk){ + case RDS_BLK_A: + ret = (cbc & 0xF000) >> 12; + break; + case RDS_BLK_B: + ret = (cbc & 0x0F00) >> 8; + break; + case RDS_BLK_C: + ret = (cbc & 0x00F0) >> 4; + break; + case RDS_BLK_D: + ret = (cbc & 0x000F) >> 0; + break; + default: + break; + } + FM_LOG_INF(D_RDS,"group cbc=0x%04x\n", cbc); + return ret; +} + +/* + * rds_event_set + * To set rds event, and user space can use this flag to juge which event happened + * If success return 0, else return error code +*/ +static int rds_event_set(uint16_t *events, int event_mask){ + int ret = 0; + + FM_ASSERT(events); + *events |= event_mask; + + return ret; +} + +/* + * rds_flag_set + * To set rds event flag, and user space can use this flag to juge which event happened + * If success return 0, else return error code +*/ +static int rds_flag_set(uint32_t *flags, int flag_mask){ + int ret = 0; + + FM_ASSERT(flags); + *flags |= flag_mask; + + return ret; +} + +/* + * rds_group_type_get + * To get rds group type form blockB + * If success return 0, else return error code +*/ +static int rds_group_type_get(uint16_t crc, uint16_t blk, uint8_t *type, uint8_t *subtype){ + int ret = 0; + bool valid = FALSE; + + FM_ASSERT(type); + FM_ASSERT(subtype); + //to get the group type from block B + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_B, &valid); + if(valid == TRUE){ + *type = (blk & 0xF000)>>12; //Group type(4bits) + *subtype = (blk & 0x0800)>>11; //version code(1bit), 0=vesionA, 1=versionB + }else{ + FM_LOG_WAR(D_RDS,"Block1 CRC err\n"); + return -ERR_RDS_CRC; + } + + FM_LOG_INF(D_RDS,"Type=%d, subtype:%s\n", (int)*type, *subtype ? "version B" : "version A"); + return ret; +} + +/* + * rds_group_counter_add + * @type -- group type, rang: 0~15 + * @subtype -- sub group type, rang:0~1 + * + * add group counter, group0a~group15b + * we use type value as the index + * If success return 0, else return error code +*/ +static int rds_group_counter_add(uint8_t type, uint8_t subtype, struct rds_group_cnt *gc) +{ + FM_ASSERT(gc); + + if(type > 15){ + return -ERR_INVALID_PARA; + } + switch(subtype){ + case RDS_GRP_VER_A: + gc->groupA[type]++; + break; + case RDS_GRP_VER_B: + gc->groupB[type]++; + break; + default: + return -ERR_INVALID_PARA; + break; + } + gc->total++; + FM_LOG_INF(D_RDS,"group counter:%d\n", (int)gc->total); + return 0; +} + +/* + * rds_group_counter_get + * + * read group counter , group0a~group15b + * If success return 0, else return error code +*/ +extern int rds_group_counter_get(struct rds_group_cnt *dst, struct rds_group_cnt *src) +{ + FM_ASSERT(dst); + FM_ASSERT(src); + memcpy(dst, src, sizeof(struct rds_group_cnt)); + return 0; +} + +/* + * rds_group_counter_reset + * + * clear group counter to 0, group0a~group15b + * If success return 0, else return error code +*/ +extern int rds_group_counter_reset(struct rds_group_cnt *gc) +{ + FM_ASSERT(gc); + memset(gc, 0, sizeof(struct rds_group_cnt)); + return 0; +} + +/* + * rds_group_pi_get + * To get rds group pi code form blockA + * If success return 0, else return error code +*/ +static int rds_group_pi_get(uint16_t crc, uint16_t blk, uint16_t *pi, bool *dirty){ + int ret = 0; + bool valid = FALSE; + + FM_ASSERT(pi); + FM_ASSERT(dirty); + + //to get the group pi code from block A + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_A, &valid); + if(valid == TRUE){ + if(*pi != blk){ + //PI=program Identication + *pi = blk; + *dirty = TRUE; // yes, we got new PI code + }else{ + *dirty = FALSE; // PI is the same as last one + } + }else{ + FM_LOG_WAR(D_RDS,"Block0 CRC err\n"); + return -ERR_RDS_CRC; + } + + FM_LOG_INF(D_RDS,"PI=0x%04x, %s\n", *pi, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_group_pty_get + * To get rds group pty code form blockB + * If success return 0, else return error code +*/ +static int rds_group_pty_get(uint16_t crc, uint16_t blk, uint8_t *pty, bool *dirty){ + int ret = 0; + bool valid = FALSE; + + FM_ASSERT(pty); + FM_ASSERT(dirty); + + //to get PTY code from block B + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_B, &valid); + if(valid == FALSE){ + FM_LOG_WAR(D_RDS,"Block1 CRC err\n"); + return -ERR_RDS_CRC; + } + + if(*pty != ((blk & 0x03E0)>>5)){ + //PTY=Program Type Code + *pty = (blk&0x03E0)>>5; + *dirty = TRUE; // yes, we got new PTY code + }else{ + *dirty = FALSE; // PTY is the same as last one + } + + FM_LOG_INF(D_RDS,"PTY=%d, %s\n", (int)*pty, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_group_tp_get + * To get rds group tp code form blockB + * If success return 0, else return error code +*/ +static int rds_group_tp_get(uint16_t crc, uint16_t blk, uint8_t *tp, bool *dirty){ + int ret = 0; + bool valid = FALSE; + + FM_ASSERT(tp); + FM_ASSERT(dirty); + + //to get TP code from block B + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_B, &valid); + if(valid == FALSE){ + FM_LOG_WAR(D_RDS,"Block1 CRC err\n"); + return -ERR_RDS_CRC; + } + + if(*tp != ((blk&0x0400)>>10)){ + //Tranfic Program Identification + *tp = (blk&0x0400)>>10; + *dirty = TRUE; // yes, we got new TP code + }else{ + *dirty = FALSE; // TP is the same as last one + } + + FM_LOG_INF(D_RDS,"TP=%d, %s\n", (int)*tp, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_group0_ta_get + * To get rds group ta code form blockB + * If success return 0, else return error code +*/ +static int rds_group0_ta_get(uint16_t blk, uint8_t *ta, bool *dirty){ + int ret = 0; + + FM_ASSERT(ta); + FM_ASSERT(dirty); + //TA=Traffic Announcement code + if(*ta != ((blk & 0x0010)>>4)){ + *ta = (blk & 0x0010)>>4; + *dirty = TRUE; // yes, we got new TA code + }else{ + *dirty = FALSE; // TA is the same as last one + } + + FM_LOG_INF(D_G0,"TA=%d, %s\n", (int)*ta, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_group0_music_get + * To get music-speech switch code form blockB + * If success return 0, else return error code +*/ +static int rds_group0_music_get(uint16_t blk, uint8_t *music, bool *dirty){ + int ret = 0; + + FM_ASSERT(music); + FM_ASSERT(dirty); + //M/S=music speech switch code + if(*music != ((blk & 0x0008)>>3)){ + *music = (blk & 0x0008)>>3; + *dirty = TRUE; // yes, we got new music code + }else{ + *dirty = FALSE; // music is the same as last one + } + + FM_LOG_INF(D_G0,"Music=%d, %s\n", (int)*music, *dirty ? "new" : "old"); + return ret; +} + +/* + * rds_group2_rt_addr_get + * To get rt addr form blockB + * If success return 0, else return error code +*/ +static int rds_group2_rt_addr_get(uint16_t blk, uint8_t *addr){ + int ret = 0; + + FM_ASSERT(addr); + *addr = (uint8_t)blk & 0x0F; + + FM_LOG_INF(D_G2,"addr=0x%02x\n", *addr); + return ret; +} + +static int rds_group2_txtAB_get(uint16_t blk, uint8_t *txtAB, bool *dirty){ + int ret = 0; + + FM_ASSERT(txtAB); + FM_ASSERT(dirty); + + if(*txtAB != ((blk&0x0010)>>4)){ + *txtAB = (blk&0x0010)>>4; + *dirty = TRUE; // yes, we got new txtAB code + }else{ + *dirty = FALSE; // txtAB is the same as last one + } + + FM_LOG_INF(D_G2,"txtAB=%d, %s\n", *txtAB, *dirty ? "new" : "old"); + return ret; +} + +static int rds_group2_rt_get(uint16_t crc, uint8_t subtype, uint16_t blkC, uint16_t blkD, uint8_t addr, uint8_t *buf){ + int ret = 0; + bool valid = FALSE; + int idx = 0; + + FM_ASSERT(buf); + //text segment addr rang 0~15 + if(addr > 0xFF){ + FM_LOG_ERR(D_RDS,"addr invalid(0x%02x)\n", addr); + ret = -ERR_INVALID_PARA; + return ret; + } + switch(subtype){ + case RDS_GRP_VER_A: + idx = 4*addr; + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_C | FM_RDS_GDBK_IND_D, &valid); + if(valid == TRUE){ + buf[idx] = blkC>>8; + buf[idx+1] = blkC&0xFF; + buf[idx+2] = blkD>>8; + buf[idx+3] = blkD&0xFF; + }else{ + FM_LOG_ERR(D_RDS,"rt crc check err\n"); + ret = -ERR_RDS_CRC; + } + break; + case RDS_GRP_VER_B: + idx = 2*addr; + ret = rds_checksum_check(crc, FM_RDS_GDBK_IND_D, &valid); + if(valid == TRUE){ + buf[idx] = blkD>>8; + buf[idx+1] = blkD&0xFF; + }else{ + FM_LOG_ERR(D_RDS,"rt crc check err\n"); + ret = -ERR_RDS_CRC; + } + break; + default: + break; + } + + FM_LOG_INF(D_G2,"addr[%02x]:0x%02x 0x%02x 0x%02x 0x%02x\n", addr, buf[idx], buf[idx+1], buf[idx+2], buf[idx+3]); + return ret; +} + +static int rds_group2_rt_get_len(uint8_t subtype, int pos, int *len){ + int ret = 0; + + FM_ASSERT(len); + if(subtype == RDS_GRP_VER_A){ + *len = 4*(pos+1); + }else{ + *len = 2*(pos+1); + } + + return ret; +} + +/* + * rds_group2_rt_cmp + * this function is the most importent flow for RT parsing + * 1.Compare fresh buf with once buf per byte, if eque copy this byte to twice buf, else copy it to once buf + * 2.Check wether we got a full segment, for typeA if copyed 4bytes to twice buf, for typeB 2bytes copyed to twice buf + * 3.Check wether we got the end of RT, if we got 0x0D + * 4.If we got the end, then caculate the RT lenth + * If success return 0, else return error code +*/ +static int rds_group2_rt_cmp(uint8_t addr, uint16_t cbc, uint8_t subtype, uint8_t *fresh, + uint8_t *once, uint8_t *twice, bool *valid, bool *end, int *len){ + int ret = 0; + int i = 0; + int j = 0; + int cnt = 0; + + FM_ASSERT(fresh); + FM_ASSERT(once); + FM_ASSERT(twice); + FM_ASSERT(valid); + FM_ASSERT(end); + + j = (subtype == RDS_GRP_VER_A) ? 4 : 2; // RT segment width + if(subtype == RDS_GRP_VER_A){ + if(rds_cbc_get(cbc, RDS_BLK_C) == 0){ + once[j*addr+0] = fresh[j*addr+0]; + once[j*addr+1] = fresh[j*addr+1]; + } + if(rds_cbc_get(cbc, RDS_BLK_D) == 0){ + once[j*addr+2] = fresh[j*addr+2]; + once[j*addr+3] = fresh[j*addr+3]; + } + }else if(subtype == RDS_GRP_VER_B){ + if(rds_cbc_get(cbc, RDS_BLK_D) == 0){ + once[j*addr+0] = fresh[j*addr+0]; + once[j*addr+1] = fresh[j*addr+1]; + } + } + + for(i = 0; i < j; i++){ + if(fresh[j*addr+i] == once[j*addr+i]){ + twice[j*addr+i] = once[j*addr+i]; //get the same byte 2 times + cnt++; + }else{ + once[j*addr+i] = fresh[j*addr+i]; //use new val + } + + //if we got 0x0D twice, it means a RT end + if(twice[j*addr+i] == 0x0D){ + *end = TRUE; + *len = j*addr+i+1; //record the length of RT + } + } + + //check if we got a valid segment 4bytes for typeA, 2bytes for typeB + if(cnt == j){ + *valid = TRUE; + }else{ + *valid = FALSE; + } + FM_LOG_INF(D_G2,"RT seg=%s\n", *valid == TRUE ? "TRUE" : "FALSE"); + FM_LOG_INF(D_G2,"RT end=%s\n", *end == TRUE ? "TRUE" : "FALSE"); + FM_LOG_INF(D_G2,"RT len=%d\n", *len); + return ret; +} + +static uint16_t rds_group2_rt_addr_bitmap_get(uint16_t bitmap){ + return bitmap; +} + +static int rds_group2_rt_addr_bitmap_get_pos(uint16_t bitmap){ + int i = 15; + while(!(bitmap & (1< -1)){ + i--; + } + return i; +} + +#if 0 +static bool rds_group2_rt_addr_bitmap_test(uint16_t bitmap, uint8_t addr){ + return (bitmap & (1< bitmap2, return positive(+) + * If bitmap1 = bitmap2, return 0 + * If bitmap1 < bitmap2, return nagotive(-) + */ +static int rds_group2_rt_addr_bitmap_cmp(uint16_t bitmap1, uint16_t bitmap2) +{ + return (int)(bitmap1 - bitmap2); +} + +static int rds_group2_rt_addr_bitmap_set(uint16_t *bitmap, int *bm_cnt, uint8_t addr){ + int ret = 0; + uint16_t bm_old = 0; + + FM_ASSERT(bitmap); + FM_ASSERT(bm_cnt); + //text segment addr rang 0~15 + if(addr > 0xFF){ + FM_LOG_ERR(D_RDS,"addr invalid(0x%02x)\n", addr); + ret = -ERR_INVALID_PARA; + return ret; + } + bm_old = *bitmap; + *bitmap |= (1< 0){ + (*bm_cnt)--; + } + FM_LOG_NTC(D_G2,"RT bitmap=0x%04x, bmcnt=%d\n", *bitmap, *bm_cnt); + return ret; +} + +static RDS_RT_STATE_MACHINE rds_rt_state_get(void){ + return rt_state_machine; +} + +static RDS_RT_STATE_MACHINE rds_rt_state_set(RDS_RT_STATE_MACHINE state_new){ + rt_state_machine = state_new; + return rt_state_machine; +} + +#if 0 +static bool rds_group2_is_rt_finished(uint16_t *event){ + FM_ASSERT(event); + if(*event&RDS_EVENT_LAST_RADIOTEXT){ + return TRUE; + }else{ + return FALSE; + } +} +#endif + +static int MT6620_RDS_enable(void) +{ + uint16_t page; + int ret = 0; + + if((ret = MT6620_read(FM_MAIN_PGSEL, &page))) + return ret; + + if((ret = MT6620_write(0x9F, 0x0003))) + return ret; + if((ret = MT6620_write(0xCB, 0xE016))) + return ret; + if((ret = MT6620_write(0x9F, 0x0000))) + return ret; + if((ret = MT6620_write(0x63, 0x0491))) + return ret; + if((ret = MT6620_set_bits(0x6B, 0x2000, 0xFFFF))) + return ret; + + ret = MT6620_write(FM_MAIN_PGSEL, page); + + return ret; +} + +static int MT6620_RDS_disable(void) +{ + int ret = 0; + if((ret = MT6620_set_bits(0x6B, 0x0000, 0xDFFF))) + return ret; + ret = MT6620_write(0x63, 0x0481); + + return ret; +} + +static int MT6620_RDS_Get_GoodBlock_Counter(uint16_t* pCnt) +{ + uint16_t tmp_reg; + uint16_t page; + int ret = 0; + + if(NULL == pCnt) + return -ERR_INVALID_BUF; + + if((ret = MT6620_read(FM_MAIN_PGSEL, &page))) + return ret; + + if((ret = MT6620_write(0x9F, 0x0003))) + return ret; + if((ret = MT6620_read(0xC6, &tmp_reg))) + return ret; + + ret = MT6620_write(FM_MAIN_PGSEL, page); + + *pCnt = tmp_reg; + return ret; +} + +static int MT6620_RDS_Get_BadBlock_Counter(uint16_t* pCnt) +{ + uint16_t tmp_reg; + uint16_t page; + int ret = 0; + + if(NULL == pCnt) + return -ERR_INVALID_BUF; + + if((ret = MT6620_read(FM_MAIN_PGSEL, &page))) + return ret; + + if((ret = MT6620_write(0x9F, 0x0003))) + return ret; + if((ret = MT6620_read(0xC7, &tmp_reg))) + return ret; + + ret = MT6620_write(FM_MAIN_PGSEL, page); + + *pCnt = tmp_reg; + return ret; +} + + +static int MT6620_RDS_Reset_Block_Counter(void) +{ + uint16_t page; + int ret = 0; + + if((ret = MT6620_read(FM_MAIN_PGSEL, &page))) + return ret; + + if((ret = MT6620_write(0x9F, 0x0003))) + return ret; + if((ret = MT6620_write(0xC8, 0x0001))) + return ret; + if((ret = MT6620_write(0xC8, 0x0002))) + return ret; + + ret = MT6620_write(FM_MAIN_PGSEL, page); + + return ret; +} + +static int MT6620_RDS_Reset(void) +{ + uint16_t page; + int ret = 0; + + if((ret = MT6620_read(FM_MAIN_PGSEL, &page))) + return ret; + + if((ret = MT6620_write(0x9F, 0x0003))) + return ret; + if((ret = MT6620_write(0xB0, 0x0001))) + return ret; + + ret = MT6620_write(FM_MAIN_PGSEL, page); + + return ret; +} + +static int MT6620_RDS_Reset_Block(void) +{ + uint16_t page; + int ret = 0; + + if((ret = MT6620_read(FM_MAIN_PGSEL, &page))) + return ret; + + if((ret = MT6620_write(0x9F, 0x0003))) + return ret; + if((ret = MT6620_write(0xDD, 0x0001))) + return ret; + + ret = MT6620_write(FM_MAIN_PGSEL, page); + + return ret; +} + +int MT6620_RDS_BlerCheck(struct fm *fm) +{ + RDSData_Struct *pstRDSData = fm->pstRDSData; + uint16_t TOTAL_CNT; + int ret = 0; + + FM_LOG_DBG(D_BLKC,"+T:%d, MT6620_RDS_BlerCheck\n", jiffies_to_msecs(jiffies)); + + if(pstRDSData->AF_Data.Addr_Cnt == 0xFF){ + //AF List Finished + pstRDSData->event_status |= RDS_EVENT_AF; //Need notfiy application + //loop pstRDSData->event_status then act + if(pstRDSData->event_status != 0){ + fm->RDS_Data_ready = true; + wake_up_interruptible(&fm->read_wait); + FM_LOG_DBG(D_BLKC,"RDS_EVENT_AF, trigger read\n"); + } + } + + gBLER_CHK_INTERVAL = MT6620_RDS_BLER_T1; + if((ret = MT6620_RDS_Get_GoodBlock_Counter(&GOOD_BLK_CNT))) + return ret; + FM_LOG_DBG(D_BLKC,"-T:%d, GOOD_BLK_CNT:%d\n", jiffies_to_msecs(jiffies), GOOD_BLK_CNT); + if((ret = MT6620_RDS_Get_BadBlock_Counter(&BAD_BLK_CNT))) + return ret; + TOTAL_CNT = GOOD_BLK_CNT + BAD_BLK_CNT; + if((ret = MT6620_RDS_Reset_Block_Counter())) + return ret; + FM_LOG_DBG(D_BLKC,"BLER: TOTAL_CNT:%d BAD_BLK_CNT:%d, RDS_Sync_Cnt:%d\n", TOTAL_CNT, BAD_BLK_CNT, RDS_Sync_Cnt); + + if((GOOD_BLK_CNT==0)&&(BAD_BLK_CNT==0)){ + BAD_BLK_RATIO = 0; + }else{ + BAD_BLK_RATIO = (BAD_BLK_CNT*100)/TOTAL_CNT; + } + + //MT6620_RDS_BLER_TH1 90 + //MT6620_RDS_BLER_TH2 60 + //MT6620_RDS_BLER_C1 12 + //MT6620_RDS_BLER_C2 6 + //MT6620_RDS_BLER_T2 5000 + if((BAD_BLK_RATIO < MT6620_RDS_BLER_TH2)&&(RDS_Sync_Cnt > MT6620_RDS_BLER_C1)){ + gBLER_CHK_INTERVAL = MT6620_RDS_BLER_T2; + if(RDS_Block_Reset_Cnt > 1) + RDS_Block_Reset_Cnt--; + }else{ + if(BAD_BLK_RATIO > MT6620_RDS_BLER_TH1){ + //>90% + if((ret = MT6620_RDS_Reset_Block_Counter())) + return ret; + RDS_Sync_Cnt = 0; //need clear or not, Question, LCH. + RDS_Block_Reset_Cnt++; + if((RDS_Block_Reset_Cnt > MT6620_RDS_BLER_C2)||bRDS_FirstIn){ + if(bRDS_FirstIn) + bRDS_FirstIn = false; + if((ret = MT6620_RDS_Reset())) + return ret; + RDS_Block_Reset_Cnt = 0; + FM_LOG_DBG(D_BLKC,"RDS Reset, blk_cnt:%d, RDS_FirstIn:%d\n", RDS_Block_Reset_Cnt, bRDS_FirstIn); + }else if(TOTAL_CNT > 12){ + //LCH question 2, why 12??? + FM_LOG_DBG(D_BLKC,"RDS Block Reset: %x\n", RDS_Block_Reset_Cnt); + if((ret = MT6620_RDS_Reset_Block())) + return ret; + } + }else{ + RDS_Sync_Cnt++; //(60%-90%) + FM_LOG_DBG(D_BLKC,"RDS Sync Cnt: %d\n", RDS_Block_Reset_Cnt); + if(RDS_Block_Reset_Cnt > 1) + RDS_Block_Reset_Cnt--; + if(RDS_Sync_Cnt > MT6620_RDS_BLER_C1){ + gBLER_CHK_INTERVAL = MT6620_RDS_BLER_T2; + } + } + } + + return ret; +} + +static int MT6620_RDS_Init_Data(RDSData_Struct *pstRDSData) +{ + uint8_t indx; + int ret = 0; + + memset(pstRDSData, 0 ,sizeof(RDSData_Struct)); + bRDS_FirstIn = true; + + pstRDSData->PTY = 0xFF; //to avoid "rx PTY == 0" case, this will cause no PTY event + + for(indx = 0; indx < 64; indx++){ + pstRDSData->RT_Data.TextData[0][indx]=0x20; + pstRDSData->RT_Data.TextData[1][indx]=0x20; + } + for(indx = 0; indx < 8; indx++){ + pstRDSData->PS_Data.PS[0][indx] = '\0'; + pstRDSData->PS_Data.PS[1][indx] = '\0'; + pstRDSData->PS_Data.PS[2][indx] = '\0'; + pstRDSData->PS_ON[indx] = 0x20; + } + + return ret; +} + +static int MT6620_RDS_RetrieveGroup0(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData) +{ + uint8_t indx, indx2, DI_Code, DI_Flag, PS_Num, AF_H, AF_L, num; + int ret = 0; + bool valid = FALSE; + bool dirty = FALSE; + uint16_t *event = &pstRDSData->event_status; + uint32_t *flag = &pstRDSData->RDSFlag.flag_status; + + ret = rds_checksum_check(block_data[4], FM_RDS_GDBK_IND_D, &valid); + if(valid == FALSE){ + FM_LOG_WAR(D_G0,"Group0 BlockD crc err\n"); + return -ERR_RDS_CRC; + } + + ret = rds_group0_ta_get(block_data[1], &pstRDSData->RDSFlag.TA, &dirty); + if(ret){ + FM_LOG_WAR(D_G0,"get ta failed[ret=%d]\n", ret); + }else if(dirty == TRUE){ + ret = rds_event_set(event, RDS_EVENT_FLAGS); // yes, we got new TA code + ret = rds_flag_set(flag, RDS_FLAG_IS_TA); + } + + ret = rds_group0_music_get(block_data[1], &pstRDSData->RDSFlag.Music, &dirty); + if(ret){ + FM_LOG_WAR(D_G0,"get music failed[ret=%d]\n", ret); + }else if(dirty == TRUE){ + ret = rds_event_set(event, RDS_EVENT_FLAGS); // yes, we got new MUSIC code + ret = rds_flag_set(flag, RDS_FLAG_IS_MUSIC); + } + + if((pstRDSData->Switch_TP)&&(pstRDSData->RDSFlag.TP)&&!(pstRDSData->RDSFlag.TA)){ + ret = rds_event_set(event, RDS_EVENT_TAON_OFF); + } + + if(!SubType){ + //Type A + ret = rds_checksum_check(block_data[4], FM_RDS_GDBK_IND_C, &valid); + if(valid == FALSE){ + FM_LOG_WAR(D_G0,"Group0 BlockC crc err\n"); + return -ERR_RDS_CRC; + }else{ + AF_H = (block_data[2]&0xFF00)>>8; + AF_L= block_data[2]&0x00FF; + + if((AF_H > 224)&&(AF_H < 250)){ + //Followed AF Number, see RDS spec Table 11, valid(224-249) + FM_LOG_DBG(D_G0,"RetrieveGroup0 AF_H:%d, AF_L:%d\n", AF_H, AF_L); + pstRDSData->AF_Data.isAFNum_Get = 0; + preAF_Num = AF_H - 224; //AF Number + if(preAF_Num != pstRDSData->AF_Data.AF_Num){ + pstRDSData->AF_Data.AF_Num = preAF_Num; + }else{ + //Get the same AFNum two times + pstRDSData->AF_Data.isAFNum_Get = 1; + } + + if((AF_L < 205) && (AF_L > 0)){ + //See RDS Spec table 10, valid VHF + pstRDSData->AF_Data.AF[0][0] = AF_L+875; //convert to 100KHz + FM_LOG_DBG(D_G0,"RetrieveGroup0 AF[0][0]:%d\n", pstRDSData->AF_Data.AF[0][0]); + if((pstRDSData->AF_Data.AF[0][0]) != (pstRDSData->AF_Data.AF[1][0])){ + pstRDSData->AF_Data.AF[1][0] = pstRDSData->AF_Data.AF[0][0]; + }else{ + if(pstRDSData->AF_Data.AF[1][0] != _current_frequency) + pstRDSData->AF_Data.isMethod_A = 1; + else + pstRDSData->AF_Data.isMethod_A = 0; + } + + FM_LOG_DBG(D_G0,"RetrieveGroup0 isAFNum_Get:%d, isMethod_A:%d\n", pstRDSData->AF_Data.isAFNum_Get, pstRDSData->AF_Data.isMethod_A); + + //only one AF handle + if((pstRDSData->AF_Data.isAFNum_Get)&& (pstRDSData->AF_Data.AF_Num == 1)){ + pstRDSData->AF_Data.Addr_Cnt = 0xFF; + pstRDSData->event_status |= RDS_EVENT_AF_LIST; + FM_LOG_DBG(D_G0,"RetrieveGroup0 RDS_EVENT_AF_LIST update\n"); + } + } + } + else if((pstRDSData->AF_Data.isAFNum_Get)&&(pstRDSData->AF_Data.Addr_Cnt != 0xFF)){ + //AF Num correct + num = pstRDSData->AF_Data.AF_Num; + num = num>>1; + FM_LOG_DBG(D_G0,"RetrieveGroup0 +num:%d\n", num); + + //Put AF freq into buffer and check if AF freq is repeat again + for(indx = 1; indx < (num+1); indx++){ + if((AF_H == (pstRDSData->AF_Data.AF[0][2*num-1]))&&(AF_L == (pstRDSData->AF_Data.AF[0][2*indx]))){ + FM_LOG_ERR(D_G0|D_ALL,"RetrieveGroup0 AF same as indx:%d\n", indx); + break; + }else if(!(pstRDSData->AF_Data.AF[0][2*indx-1])){ + //null buffer + pstRDSData->AF_Data.AF[0][2*indx-1] = AF_H+875; //convert to 100KHz + pstRDSData->AF_Data.AF[0][2*indx] = AF_L+875; + FM_LOG_DBG(D_G0,"RetrieveGroup0 AF[0][%d]:%d, AF[0][%d]:%d\n", + 2*indx-1, pstRDSData->AF_Data.AF[0][2*indx-1], 2*indx, pstRDSData->AF_Data.AF[0][2*indx]); + break; + } + } + num = pstRDSData->AF_Data.AF_Num; + FM_LOG_DBG(D_G0,"RetrieveGroup0 ++num:%d\n", num); + if(num > 0){ + if((pstRDSData->AF_Data.AF[0][num-1]) != 0){ + num = num>>1; + FM_LOG_DBG(D_G0,"RetrieveGroup0 +++num:%d\n", num); + //arrange frequency from low to high:start + for(indx = 1; indx < num; indx++){ + for(indx2 = indx+1; indx2 < (num+1); indx2++){ + AF_H = pstRDSData->AF_Data.AF[0][2*indx-1]; + AF_L = pstRDSData->AF_Data.AF[0][2*indx]; + if(AF_H > (pstRDSData->AF_Data.AF[0][2*indx2-1])){ + pstRDSData->AF_Data.AF[0][2*indx-1] = pstRDSData->AF_Data.AF[0][2*indx2-1]; + pstRDSData->AF_Data.AF[0][2*indx] = pstRDSData->AF_Data.AF[0][2*indx2]; + pstRDSData->AF_Data.AF[0][2*indx2-1] = AF_H; + pstRDSData->AF_Data.AF[0][2*indx2] = AF_L; + }else if(AF_H == (pstRDSData->AF_Data.AF[0][2*indx2-1])){ + if(AF_L > (pstRDSData->AF_Data.AF[0][2*indx2])){ + pstRDSData->AF_Data.AF[0][2*indx-1] = pstRDSData->AF_Data.AF[0][2*indx2-1]; + pstRDSData->AF_Data.AF[0][2*indx] = pstRDSData->AF_Data.AF[0][2*indx2]; + pstRDSData->AF_Data.AF[0][2*indx2-1] = AF_H; + pstRDSData->AF_Data.AF[0][2*indx2] = AF_L; + } + } + } + } + //arrange frequency from low to high:end + //compare AF buff0 and buff1 data:start + num = pstRDSData->AF_Data.AF_Num; + indx2 = 0; + + for(indx = 0; indx < num; indx++){ + if((pstRDSData->AF_Data.AF[1][indx]) == (pstRDSData->AF_Data.AF[0][indx])){ + if(pstRDSData->AF_Data.AF[1][indx] != 0) + indx2++; + }else + pstRDSData->AF_Data.AF[1][indx] = pstRDSData->AF_Data.AF[0][indx]; + } + FM_LOG_DBG(D_G0,"RetrieveGroup0 indx2:%d, num:%d\n", indx2, num); + //compare AF buff0 and buff1 data:end + if(indx2 == num){ + pstRDSData->AF_Data.Addr_Cnt = 0xFF; + pstRDSData->event_status |= RDS_EVENT_AF_LIST; + FM_LOG_DBG(D_G0,"RetrieveGroup0 AF_Num:%d\n", pstRDSData->AF_Data.AF_Num); + for(indx = 0; indx < num; indx++){ + if((pstRDSData->AF_Data.AF[1][indx]) == 0){ + pstRDSData->AF_Data.Addr_Cnt = 0x0F; + pstRDSData->event_status &= (~RDS_EVENT_AF_LIST); + } + } + } + else + pstRDSData->AF_Data.Addr_Cnt = 0x0F; + } + } + } + } + } + + /*DI_Code[1:0]: "00" = d3 * + * "01" = d2 * + * "10" = d1 * + * "11" = d0 */ + + DI_Code = block_data[1]&0x0003; //DI=decoder identification code. + DI_Flag = (block_data[1]&0x0004)>>2; + + switch(DI_Code){ + case 3: + if(pstRDSData->RDSFlag.Stereo != DI_Flag){ + pstRDSData->RDSFlag.Stereo = DI_Flag; + pstRDSData->event_status |= RDS_EVENT_FLAGS; + pstRDSData->RDSFlag.flag_status |= RDS_FLAG_IS_STEREO; + } + break; + case 2: + if(pstRDSData->RDSFlag.Artificial_Head != DI_Flag){ + pstRDSData->RDSFlag.Artificial_Head = DI_Flag; + pstRDSData->event_status |= RDS_EVENT_FLAGS; + pstRDSData->RDSFlag.flag_status |= RDS_FLAG_IS_ARTIFICIAL_HEAD; + } + break; + case 1: + if(pstRDSData->RDSFlag.Compressed != DI_Flag){ + pstRDSData->RDSFlag.Compressed = DI_Flag; + pstRDSData->event_status |= RDS_EVENT_FLAGS; + pstRDSData->RDSFlag.flag_status |= RDS_FLAG_IS_COMPRESSED; + } + break; + case 0: + if(pstRDSData->RDSFlag.Dynamic_PTY != DI_Flag){ + pstRDSData->RDSFlag.Dynamic_PTY = DI_Flag; + pstRDSData->event_status |= RDS_EVENT_FLAGS; + pstRDSData->RDSFlag.flag_status |= RDS_FLAG_IS_DYNAMIC_PTY; + } + break; + default: + break; + } + + PS_Num = block_data[1]&0x0003; //Figure 12 Type 0 group. + AF_H = pstRDSData->PS_Data.PS[0][2*PS_Num]; + AF_L = pstRDSData->PS_Data.PS[0][2*PS_Num+1]; + if((AF_H == (block_data[3])>>8)&&(AF_L == (block_data[3]&0xFF))){ + if((!((pstRDSData->event_status)&RDS_EVENT_PROGRAMNAME))&&((PS_Num == 0)||(pstRDSData->PS_Data.Addr_Cnt))){ + pstRDSData->PS_Data.PS[1][2*PS_Num]=(block_data[3])>>8; + pstRDSData->PS_Data.PS[1][2*PS_Num+1] = (block_data[3])&0xFF; + FM_LOG_DBG(D_G0,"RetrieveGroup0 PS second time, NUM:%x H:%x L:%x\n", + PS_Num, pstRDSData->PS_Data.PS[1][2*PS_Num], pstRDSData->PS_Data.PS[1][2*PS_Num+1]); + + //Need clear buff0, LCH question 1, should clear not not? + if((PS_Num == 0)&&(pstRDSData->PS_Data.Addr_Cnt == 0)){ + for(indx = 2; indx < 8; indx++){ + pstRDSData->PS_Data.PS[0][indx] = '\0'; //clear buff0 + } + } + pstRDSData->PS_Data.Addr_Cnt |= 1<PS_Data.Addr_Cnt); + if(pstRDSData->PS_Data.Addr_Cnt == 0x0F){ + //Avoid PS transient:Start + num = 0; + for(indx = 0; indx < 8; indx++){ + if(pstRDSData->PS_Data.PS[0][indx] == pstRDSData->PS_Data.PS[1][indx]) + num++; + } + pstRDSData->PS_Data.Addr_Cnt = 0; + //Avoid PS transient:END + + if(num == 8){ + // get same data 2 times + num = 0; + for(indx = 0; indx < 8; indx++){ + if(pstRDSData->PS_Data.PS[1][indx] == pstRDSData->PS_Data.PS[2][indx]) + num++; + } + //if(num != 8) //get same data 2 times, and not same as the last show. + pstRDSData->event_status |= RDS_EVENT_PROGRAMNAME; + + for(indx = 0; indx < 8; indx++){ + pstRDSData->PS_Data.PS[2][indx] = pstRDSData->PS_Data.PS[1][indx]; + pstRDSData->PS_Data.PS[1][indx] = '\0'; + pstRDSData->PS_Data.PS[0][indx] = '\0'; + } + }else{ + pstRDSData->PS_Data.Addr_Cnt |= 1<PS_Data.PS[0][2*PS_Num]=(block_data[3])>>8; + pstRDSData->PS_Data.PS[0][2*PS_Num+1] = (block_data[3])&0xFF; + FM_LOG_DBG(D_G0,"RetrieveGroup0 PS, NUM:%x H:%x L:%x\n", + PS_Num, pstRDSData->PS_Data.PS[0][2*PS_Num], pstRDSData->PS_Data.PS[0][2*PS_Num+1]); + } + + if((pstRDSData->event_status)&RDS_EVENT_PROGRAMNAME){ + PS_Num = 0; + for(num = 0; num < 8;num++){ + if(pstRDSData->PS_Data.PS[2][num] == '\0') + PS_Num |= 1<event_status &= (~RDS_EVENT_PROGRAMNAME); + } + } + + return ret; +} + +static int MT6620_RDS_RetrieveGroup1(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData) +{ + uint8_t variant_code = (block_data[2]&0x7000)>>12; + int ret = 0; + + if(variant_code == 0){ + pstRDSData->Extend_Country_Code = (uint8_t)block_data[2]&0xFF; + FM_LOG_DBG(D_G1,"Extend_Country_Code:%d\n", pstRDSData->Extend_Country_Code); + }else if(variant_code == 3){ + pstRDSData->Language_Code = block_data[2]&0xFFF; + FM_LOG_DBG(D_G1,"Language_Code:%d\n", pstRDSData->Language_Code); + } + + pstRDSData->Radio_Page_Code = block_data[1]&0x001F; + pstRDSData->Program_Item_Number_Code = block_data[3]; + + return ret; +} + +#ifdef FM_RDS_G2_USE_OLD +static bool PreTextABFlag; + +static int MT6620_RDS_RetrieveGroup2(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData) +{ + uint8_t TextAddr, indx, indx2, space, byte0, byte1; + uint16_t addrcnt; + int i = 0; + int ret = 0; + + TextAddr = (uint8_t)block_data[1]&0x0F; + + if(pstRDSData->RDSFlag.Text_AB != ((block_data[1]&0x0010)>>4)){ + pstRDSData->RDSFlag.Text_AB = (block_data[1]&0x0010)>>4; + pstRDSData->event_status |= RDS_EVENT_FLAGS; + pstRDSData->RDSFlag.flag_status |= RDS_FLAG_TEXT_AB; + } + FM_LOG_DBG(D_G2,"RT RetrieveGroup2 TextABFlag: %x --> %x\n", PreTextABFlag, pstRDSData->RDSFlag.Text_AB); + + if(PreTextABFlag != pstRDSData->RDSFlag.Text_AB){ // Text A/B changed, clear old RT, and get new RT + /*DDB:Some station don't send 0x0D, it just switch TextAB if it want to send next message.*/ + if (pstRDSData->RT_Data.isRTDisplay == 0) { + FM_LOG_WAR(D_G2,"RT_Data.isRTDisplay == 0, and TextAB changed\n"); + pstRDSData->event_status |= RDS_EVENT_LAST_RADIOTEXT; + space = 0; + for(indx = 0; indx < 64; indx++){ + /*DDB:Why TextData[1][0] NOT TextData[2][0], Because some station just send a message one time, and then change TextAB, send another message, SUCH As Beijing 90.0*/ + if(pstRDSData->RT_Data.TextData[1][indx] == 0x20) + space++; + } + if(space == 64) + pstRDSData->event_status &= (~RDS_EVENT_LAST_RADIOTEXT); + + if (pstRDSData->event_status & RDS_EVENT_LAST_RADIOTEXT){ + /*DDB:Why TextData[1][0] NOT TextData[2][0], Because some station just send a message one time, and then change TextAB, send another message, SUCH As Beijing 90.0*/ + memcpy(&(pstRDSData->RT_Data.TextData[3][0]), &(pstRDSData->RT_Data.TextData[1][0]), sizeof(pstRDSData->RT_Data.TextData[3])); + FM_LOG_WAR(D_G2,"RT_Data.isRTDisplay = 1, no 0x0D case.\n"); + pstRDSData->RT_Data.isRTDisplay = 1; + } + } + + //to get Radio text length + pstRDSData->RT_Data.TextLength = 0; + i = 15; + while(!(pstRDSData->RT_Data.Addr_Cnt & (1< -1)){ + i--; + } + if(!SubType){ + pstRDSData->RT_Data.TextLength = 4*(i+1); + }else{ + pstRDSData->RT_Data.TextLength = 2*(i+1); + } + FM_LOG_INF(D_G2,"RDS RT Get Len: [AddrMap=0x%x] [Length=0x%x]\n", pstRDSData->RT_Data.Addr_Cnt, pstRDSData->RT_Data.TextLength); + + /*DDB, end*/ + //clear the buffer because Text A/B changed + memset(&(pstRDSData->RT_Data.TextData[0][0]), 0x20, sizeof(pstRDSData->RT_Data.TextData[0])); + memset(&(pstRDSData->RT_Data.TextData[1][0]), 0x20, sizeof(pstRDSData->RT_Data.TextData[1])); + memset(&(pstRDSData->RT_Data.TextData[2][0]), 0x20, sizeof(pstRDSData->RT_Data.TextData[2])); + PreTextABFlag = pstRDSData->RDSFlag.Text_AB; + pstRDSData->RT_Data.GetLength = 0; + pstRDSData->RT_Data.Addr_Cnt = 0; + //pstRDSData->RT_Data.isRTDisplay = 0; + } + + if(!SubType){ + //Type A + //WCN_DBG(FM_ALERT|D_MAIN,"RetrieveGroup2 Type A RT TextAddr: 0x%x Text: 0x%x 0x%x", TextAddr, block_data[2], block_data[3]); + FM_LOG_NTC(D_G2,"%04x %04x %04x %04x %04x", block_data[0], block_data[1], block_data[2], block_data[3], block_data[4]); + pstRDSData->RT_Data.isTypeA = 1; + //to get the 4bytes RadioText + if(block_data[4]&(FM_RDS_GDBK_IND_C|FM_RDS_GDBK_IND_D)){ + pstRDSData->RT_Data.TextData[0][4*TextAddr] = block_data[2]>>8; + pstRDSData->RT_Data.TextData[0][4*TextAddr+1] = block_data[2]&0xFF; + pstRDSData->RT_Data.TextData[0][4*TextAddr+2] = block_data[3]>>8; + pstRDSData->RT_Data.TextData[0][4*TextAddr+3] = block_data[3]&0xFF; + space = 0; + + for(indx = 0; indx < 4;indx++){ + byte0 = pstRDSData->RT_Data.TextData[0][4*TextAddr+indx]; + byte1 = pstRDSData->RT_Data.TextData[1][4*TextAddr+indx]; + if (TextAddr == 0){ + //WCN_DBG(FM_ALERT|D_MAIN,"RT_Data.isRTDisplay = 0\n"); + pstRDSData->RT_Data.isRTDisplay = 0; + } + if((!(pstRDSData->event_status&RDS_EVENT_LAST_RADIOTEXT))&&(byte0 == byte1)){ + //get the same byte 2 times + space++; + pstRDSData->RT_Data.TextData[2][4*TextAddr+indx] = byte0; + }else{ + pstRDSData->RT_Data.TextData[1][4*TextAddr+indx] = byte0; + } + } + + if(space == 4){ + addrcnt = pstRDSData->RT_Data.Addr_Cnt; + pstRDSData->RT_Data.Addr_Cnt |= (1<RT_Data.Addr_Cnt); + + if(addrcnt == pstRDSData->RT_Data.Addr_Cnt){ + pstRDSData->RT_Data.BufCnt++; + }else if(pstRDSData->RT_Data.BufCnt > 0){ + pstRDSData->RT_Data.BufCnt--; + } + } + } else { + FM_LOG_ERR(D_G2|D_ALL,"RT %04x %04x %04x %04x %04x CRC error.", block_data[0], block_data[1], block_data[2], block_data[3], block_data[4]); + } + for(indx = 0; indx < 4; indx++){ + if(pstRDSData->RT_Data.TextData[2][4*TextAddr+indx] == 0x0D){ + pstRDSData->RT_Data.TextLength = 4*TextAddr+indx+1; //Add terminate charater + pstRDSData->RT_Data.TextData[2][4*TextAddr+indx] = '\0'; + pstRDSData->RT_Data.GetLength = 1; + }else if((4*TextAddr+indx) == 63 && pstRDSData->RT_Data.Addr_Cnt == 0xffff){ + //type A full data. /*add by dongbo, make sure it's TextData[2], Not TextData[1]*/ + pstRDSData->RT_Data.TextLength = 4*TextAddr+indx+1; //no terminal character + pstRDSData->RT_Data.GetLength = 1; + } + } + }else{ + //FM_LOG_DBG(D_MAIN,"RetrieveGroup2 Type B RT NUM: 0x%x Text: 0x%x", TextAddr, block_data[3]); + FM_LOG_DBG(D_G2,"RT %04x %04x %04x %04x %04x", block_data[0], block_data[1], block_data[2], block_data[3], block_data[4]); + pstRDSData->RT_Data.isTypeA = 0; + if(block_data[4]&FM_RDS_GDBK_IND_D){ + pstRDSData->RT_Data.TextData[0][2*TextAddr] = block_data[3]>>8; + pstRDSData->RT_Data.TextData[0][2*TextAddr+1] = block_data[3]&0xFF; + space = 0; + + for(indx = 0; indx < 2; indx++){ + byte0 = pstRDSData->RT_Data.TextData[0][2*TextAddr+indx]; + byte1 = pstRDSData->RT_Data.TextData[1][2*TextAddr+indx]; + + if((!((pstRDSData->event_status)&RDS_EVENT_LAST_RADIOTEXT))&&(byte0 == byte1)){ + space++; + pstRDSData->RT_Data.TextData[2][2*TextAddr+indx] = byte0; + }else{ + pstRDSData->RT_Data.TextData[1][2*TextAddr+indx] = byte0; + } + } + if(space == 2){ + addrcnt = pstRDSData->RT_Data.Addr_Cnt; + pstRDSData->RT_Data.Addr_Cnt |= (1<RT_Data.Addr_Cnt); + + if(addrcnt == pstRDSData->RT_Data.Addr_Cnt){ + pstRDSData->RT_Data.BufCnt++; + }else if(pstRDSData->RT_Data.BufCnt > 0){ + pstRDSData->RT_Data.BufCnt--; + } + } + } else { + FM_LOG_DBG(D_G2,"RT %04x %04x %04x %04x %04x CRC error.", block_data[0], block_data[1], block_data[2], block_data[3], block_data[4]); + } + + for(indx = 0; indx < 2; indx++){ + if((pstRDSData->RT_Data.TextData[2][2*TextAddr+indx]) == 0x0D){ + //0x0D=end code + pstRDSData->RT_Data.TextLength = 2*TextAddr+indx+1; //Add terminate charater + pstRDSData->RT_Data.TextData[2][2*TextAddr+indx] = '\0'; + pstRDSData->RT_Data.GetLength = 1; + }else if((2*TextAddr+indx) == 31){ + //full data + pstRDSData->RT_Data.TextLength = 2*TextAddr+indx+1; //Add terminate charater + pstRDSData->RT_Data.TextData[2][2*TextAddr+indx] = '\0'; + pstRDSData->RT_Data.GetLength = 1; + } + } + } + + //Check if text is fully received + indx = TextAddr; + if(pstRDSData->RT_Data.GetLength == 1){ + addrcnt = 0xFFFF>>(0x0F-indx); + }else if(pstRDSData->RT_Data.BufCnt > 100){ + pstRDSData->RT_Data.BufCnt = 0; + for(indx = 15; indx >= 0; indx--){ + addrcnt = (pstRDSData->RT_Data.Addr_Cnt)&(1<RT_Data.isTypeA){ + for(indx2 = 0; indx2 < 4; indx2++){ + if(pstRDSData->RT_Data.TextData[2][4*indx+indx2] == 0x0D){ + pstRDSData->RT_Data.TextLength = 4*indx+indx2+1; + pstRDSData->RT_Data.TextData[2][4*indx+indx2] = '\0'; + } + } + }else{ + for(indx2 = 0; indx2 < 2; indx2++){ + if(pstRDSData->RT_Data.TextData[2][2*indx+indx2] == 0x0D){ + pstRDSData->RT_Data.TextLength = 2*indx+indx2+1; + pstRDSData->RT_Data.TextData[2][2*indx+indx2] = '\0'; + } + } + + } + addrcnt = 0xFFFF>>(0x0F-indx); + }else{ + if(pstRDSData->RT_Data.TextLength > 64){ + pstRDSData->RT_Data.TextLength = 64; + } + addrcnt = 0xFFFF; + } + + FM_LOG_NTC(D_G2,"RetrieveGroup2 RDS RT: Addr_Cnt: 0x%x Length: 0x%x addrcnt: 0x%x\n", pstRDSData->RT_Data.Addr_Cnt, pstRDSData->RT_Data.TextLength, addrcnt); + + if(((((pstRDSData->RT_Data.Addr_Cnt)&addrcnt) == addrcnt)||((TextAddr == 0x0f) && (pstRDSData->RT_Data.Addr_Cnt == 0xffff)))){ + //&&(pstRDSData->RT_Data.isRTDisplay == 0)) + pstRDSData->RT_Data.Addr_Cnt = 0; + //pstRDSData->RT_Data.isRTDisplay = 1; + pstRDSData->event_status |= RDS_EVENT_LAST_RADIOTEXT; + FM_LOG_DBG(D_G2,"RT RetrieveGroup2 isRTDisplay:%d\n", pstRDSData->RT_Data.isRTDisplay); + space = 0; + for(indx = 0; indx < 64; indx++){ + if(pstRDSData->RT_Data.TextData[2][indx] == 0x20) + space++; + } + if(space == 64) + pstRDSData->event_status &= (~RDS_EVENT_LAST_RADIOTEXT); + + memset(&(pstRDSData->RT_Data.TextData[1][0]), 0x20, sizeof(pstRDSData->RT_Data.TextData[1])); + memset(&(pstRDSData->RT_Data.TextData[0][0]), 0x20, sizeof(pstRDSData->RT_Data.TextData[0])); + + if (pstRDSData->event_status & RDS_EVENT_LAST_RADIOTEXT){ + memcpy(&(pstRDSData->RT_Data.TextData[3][0]), &(pstRDSData->RT_Data.TextData[2][0]), sizeof(pstRDSData->RT_Data.TextData[3])); + FM_LOG_WAR(D_G2,"RT_Data.isRTDisplay = 1\n"); + pstRDSData->RT_Data.isRTDisplay = 1; + } + } + + return ret; +} +#else +static int MT6620_RDS_RetrieveGroup2(uint16_t *source, uint8_t subtype, RDSData_Struct *target) +{ + int ret = 0; + uint16_t crc, cbc; + uint16_t blkA, blkB, blkC, blkD; + uint8_t *fresh, *once, *twice, *display; + uint16_t *event; + uint32_t *flag; + + uint8_t rt_addr = 0; + bool txtAB_change = FALSE; //text AB flag 0 --> 1 or 1-->0 meas new RT incoming + bool txt_end = FALSE; //0x0D means text end + bool seg_ok = 0; + static uint16_t bitmap_twice; + static int bitmap_cnt; + int pos = 0; + int rt_len = 0; + int bufsize = 0; + + FM_ASSERT(source); + FM_ASSERT(target); + //source + blkA = source[0]; + blkB = source[1]; + blkC = source[2]; + blkD = source[3]; + crc = source[4]; + cbc = source[5]; + //target + fresh = target->RT_Data.TextData[0]; + once = target->RT_Data.TextData[1]; + twice = target->RT_Data.TextData[2]; + display = target->RT_Data.TextData[3]; + event = &target->event_status; + flag = &target->RDSFlag.flag_status; + bufsize = sizeof(target->RT_Data.TextData[0]); + + //get basic info: addr, txtAB + if(rds_group2_rt_addr_get(blkB, &rt_addr)) + return ret; + if(rds_group2_txtAB_get(blkB, &target->RDSFlag.Text_AB, &txtAB_change)) + return ret; + + //RT parsing state machine run + while(1){ + switch(rds_rt_state_get()){ + case RDS_RT_START: + if(txtAB_change == TRUE){ + rds_rt_state_set(RDS_RT_DECISION); + break; + }else{ + if(rds_group2_rt_get(crc, subtype, blkC, blkD, rt_addr, fresh)){ + rds_rt_state_set(RDS_RT_FINISH); //if CRC error, we should not do parsing + break; + } + rds_group2_rt_cmp(rt_addr, cbc, subtype, fresh, once, twice, + &seg_ok, &txt_end, &rt_len); + if(seg_ok == TRUE){ + rds_group2_rt_addr_bitmap_set(&bitmap_twice, &bitmap_cnt, rt_addr); + } + rds_rt_state_set(RDS_RT_DECISION); + break; + } + case RDS_RT_DECISION: + if(txt_end == TRUE){ + rds_rt_state_set(RDS_RT_GETLEN); //find 0x0D, and the lenth has been recorded when do rds_group2_rt_cmp() + }else if(rds_group2_rt_addr_bitmap_get(bitmap_twice) == 0xFFFF //get max 64 chars + || (txtAB_change == TRUE) //text AB changed, + || (bitmap_cnt > RDS_RT_MULTI_REV_TH)){ //repeate many times, but no end char get + pos = rds_group2_rt_addr_bitmap_get_pos(bitmap_twice); + rds_group2_rt_get_len(subtype, pos, &rt_len); + rds_rt_state_set(RDS_RT_GETLEN); + }else{ + rds_rt_state_set(RDS_RT_FINISH); + } + break; + case RDS_RT_GETLEN: + memcpy(display, twice, bufsize); + target->RT_Data.TextLength = rt_len; + rds_event_set(event, RDS_EVENT_LAST_RADIOTEXT); //yes we got a new RT + FM_LOG_NTC(D_G2,"Yes, get an RT! [len=%d]\n", rt_len); + + rds_group2_rt_addr_bitmap_clear(&bitmap_twice, &bitmap_cnt); + //clear buf + memset(fresh, 0x20, bufsize); + memset(once, 0x20, bufsize); + memset(twice, 0x20, bufsize); + if(txtAB_change == TRUE){ + txtAB_change = FALSE; + //we need get new RT after show the old RT to the display + rds_rt_state_set(RDS_RT_START); + }else{ + rds_rt_state_set(RDS_RT_FINISH); + } + break; + case RDS_RT_FINISH: + rds_rt_state_set(RDS_RT_START); + goto out; + break; + default: + break; + } + } +out: + return ret; +} +#endif + +static int MT6620_RDS_RetrieveGroup4(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData) +{ + uint16_t year, month, k=0, D2, minute; + uint32_t MJD, D1; + int ret = 0; + FM_LOG_DBG(D_G4,"RetrieveGroup4 %d\n", SubType); + if(!SubType){ + //Type A + if((block_data[4]&FM_RDS_GDBK_IND_C)&&(block_data[4]&FM_RDS_GDBK_IND_D)){ + MJD = (uint32_t) (((block_data[1]&0x0003)<<15) + ((block_data[2]&0xFFFE)>>1)); + year = (MJD*100 - 1507820)/36525; + month = (MJD*10000-149561000-3652500*year)/306001; + if((month == 14)||(month == 15)) + k = 1; + D1 = (uint32_t)((36525*year)/100); + D2 = (uint16_t)((306001*month)/10000); + pstRDSData->CT.Year = 1900 + year + k; + pstRDSData->CT.Month = month - 1 - k*12; + pstRDSData->CT.Day = (uint16_t)(MJD - 14956 - D1 - D2); + pstRDSData->CT.Hour = ((block_data[2]&0x0001)<<4)+((block_data[3]&0xF000)>>12); + minute = (block_data[3]&0x0FC0)>>6; + + if(block_data[3]&0x0020){ + pstRDSData->CT.Local_Time_offset_signbit = 1; //0=+, 1=- + } + pstRDSData->CT.Local_Time_offset_half_hour = block_data[3]&0x001F; + if(pstRDSData->CT.Minute != minute){ + pstRDSData->CT.Minute = (block_data[3]&0x0FC0)>>6; + pstRDSData->event_status |= RDS_EVENT_UTCDATETIME; + } + } + } + + return ret; +} + +static int MT6620_RDS_RetrieveGroup14(uint16_t *block_data, uint8_t SubType, RDSData_Struct *pstRDSData) +{ + uint8_t TP_ON, TA_ON, PI_ON, PS_Num, AF_H, AF_L, indx, indx2, num; + int ret = 0; + FM_LOG_DBG(D_G14,"RetrieveGroup14 %d\n", SubType); + //SubType = (*(block_data+1)&0x0800)>>11; + PI_ON = block_data[3]; + TP_ON = block_data[1]&0x0010; + if((!SubType) && (block_data[4]&FM_RDS_GDBK_IND_C)){ + //Type A + PS_Num= block_data[1]&0x000F; + if(PS_Num <4){ + for(indx = 0; indx < 2; indx++){ + pstRDSData->PS_ON[2*PS_Num] = block_data[2]>>8; + pstRDSData->PS_ON[2*PS_Num+1] = block_data[2]&0xFF; + } + }else if(PS_Num == 4){ + AF_H = (block_data[2]&0xFF00)>>8; + AF_L = block_data[2]&0x00FF; + if((AF_H > 223)&&(AF_H < 250)){ + //Followed AF Number + pstRDSData->AFON_Data.isAFNum_Get = 0; + preAFON_Num = AF_H - 224; + if(pstRDSData->AFON_Data.AF_Num != preAFON_Num){ + pstRDSData->AFON_Data.AF_Num = preAFON_Num; + }else + pstRDSData->AFON_Data.isAFNum_Get= 1; + + if(AF_L < 205){ + pstRDSData->AFON_Data.AF[0][0] = AF_L+875; + if((pstRDSData->AFON_Data.AF[0][0]) != (pstRDSData->AFON_Data.AF[1][0])){ + pstRDSData->AFON_Data.AF[1][0] = pstRDSData->AFON_Data.AF[0][0]; + }else{ + pstRDSData->AFON_Data.isMethod_A = 1; + } + } + }else if((pstRDSData->AFON_Data.isAFNum_Get)&&((pstRDSData->AFON_Data.Addr_Cnt) != 0xFF)){ + //AF Num correct + num = pstRDSData->AFON_Data.AF_Num; + num = num>>1; + //Put AF freq into buffer and check if AF freq is repeat again + for(indx = 1; indx < (num+1); indx++){ + if((AF_H == (pstRDSData->AFON_Data.AF[0][2*indx-1]))&&(AF_L == (pstRDSData->AFON_Data.AF[0][2*indx]))){ + FM_LOG_NTC(D_G14,"RetrieveGroup14 AFON same as indx:%d\n", indx); + break; + }else if(!(pstRDSData->AFON_Data.AF[0][2*indx-1])){ + //null buffer + pstRDSData->AFON_Data.AF[0][2*indx-1] = AF_H+875; + pstRDSData->AFON_Data.AF[0][2*indx] = AF_L+875; + break; + } + } + num = pstRDSData->AFON_Data.AF_Num; + if(num > 0){ + if((pstRDSData->AFON_Data.AF[0][num-1]) != 0){ + num = num>> 1; + //arrange frequency from low to high:start + for(indx = 1; indx < num; indx++){ + for(indx2 = indx+1; indx2 < (num+1); indx2++){ + AF_H = pstRDSData->AFON_Data.AF[0][2*indx-1]; + AF_L = pstRDSData->AFON_Data.AF[0][2*indx]; + if(AF_H > (pstRDSData->AFON_Data.AF[0][2*indx2-1])){ + pstRDSData->AFON_Data.AF[0][2*indx-1] = pstRDSData->AFON_Data.AF[0][2*indx2-1]; + pstRDSData->AFON_Data.AF[0][2*indx] = pstRDSData->AFON_Data.AF[0][2*indx2]; + pstRDSData->AFON_Data.AF[0][2*indx2-1] = AF_H; + pstRDSData->AFON_Data.AF[0][2*indx2] = AF_L; + }else if(AF_H == (pstRDSData->AFON_Data.AF[0][2*indx2-1])){ + if(AF_L > (pstRDSData->AFON_Data.AF[0][2*indx2])){ + pstRDSData->AFON_Data.AF[0][2*indx-1] = pstRDSData->AFON_Data.AF[0][2*indx2-1]; + pstRDSData->AFON_Data.AF[0][2*indx] = pstRDSData->AFON_Data.AF[0][2*indx2]; + pstRDSData->AFON_Data.AF[0][2*indx2-1] = AF_H; + pstRDSData->AFON_Data.AF[0][2*indx2] = AF_L; + } + } + } + } + //arrange frequency from low to high:end + //compare AF buff0 and buff1 data:start + num = pstRDSData->AFON_Data.AF_Num; + indx2 = 0; + for(indx = 0; indx < num; indx++){ + if((pstRDSData->AFON_Data.AF[1][indx]) == (pstRDSData->AFON_Data.AF[0][indx])){ + if(pstRDSData->AFON_Data.AF[1][indx] != 0) + indx2++; + }else + pstRDSData->AFON_Data.AF[1][indx] = pstRDSData->AFON_Data.AF[0][indx]; + } + //compare AF buff0 and buff1 data:end + if(indx2 == num){ + pstRDSData->AFON_Data.Addr_Cnt = 0xFF; + pstRDSData->event_status |= RDS_EVENT_AFON_LIST; + for(indx = 0; indx < num; indx++){ + if((pstRDSData->AFON_Data.AF[1][indx]) == 0){ + pstRDSData->AFON_Data.Addr_Cnt = 0x0F; + pstRDSData->event_status &= (~RDS_EVENT_AFON_LIST); + } + } + }else + pstRDSData->AFON_Data.Addr_Cnt = 0x0F; + } + } + } + } + }else{ + //Type B + TA_ON = block_data[1]&0x0008; + FM_LOG_DBG(D_G14,"TA group14 typeB pstRDSData->RDSFlag.TP=%d pstRDSData->RDSFlag.TA=%d TP_ON=%d TA_ON=%d\n", pstRDSData->RDSFlag.TP, pstRDSData->RDSFlag.TA, TP_ON, TA_ON); + if((!pstRDSData->RDSFlag.TP)&&(pstRDSData->RDSFlag.TA)&&TP_ON&&TA_ON){ + int TA_num=0; + for (num=0;num<25;num++){ + if (pstRDSData->AFON_Data.AF[1][num] != 0){ + TA_num++; + } else { + break; + } + } + FM_LOG_NTC(D_G14,"TA set RDS_EVENT_TAON"); + if (TA_num == pstRDSData->AFON_Data.AF_Num){ + pstRDSData->event_status |= RDS_EVENT_TAON; + } + } + } + + return ret; +} + +int MT6620_RDS_OnOff(struct fm *fm, bool bFlag) +{ + int ret = 0; + RDSData_Struct *pstRDSData = fm->pstRDSData; + + if(bFlag){ + if((ret = MT6620_RDS_Init_Data(pstRDSData))) + return ret; + if((ret = MT6620_RDS_enable())) + return ret; + }else { + if((ret = MT6620_RDS_disable())) + return ret; + } + + return ret; +} + +/* + Block0: PI code(16bits) + Block1: Group type(4bits), B0=version code(1bit), TP=traffic program code(1bit), + PTY=program type code(5bits), other(5bits) + Block2: 16bits + Block3: 16bits +*/ +int MT6620_RDS_Eint_Handler(struct fm *fm, struct rds_rx *rds_raw, int rds_size) +{ + int ret = 0; + uint16_t block_data[6]; + uint8_t GroupType, SubType = 0; + int rds_cnt = 0; + int i = 0; + bool dirty = FALSE; + //target to fill the result in + RDSData_Struct *pstRDSData = fm->pstRDSData; + uint16_t *event = &pstRDSData->event_status; + uint32_t *flag = &pstRDSData->RDSFlag.flag_status; + + ret = rds_cnt_get(rds_raw, rds_size, &rds_cnt); + if(ret){ + FM_LOG_WAR(D_RDS,"get cnt err[ret=%d]\n", ret); + return ret; + } + //pstRDSData->EINT_Flag = 1; + while(rds_cnt > 0){ + ret = rds_group_get(&block_data[0], rds_raw, i); + if(ret){ + FM_LOG_WAR(D_RDS,"get group err[ret=%d]\n", ret); + goto do_next; + } + + ret = rds_group_type_get(block_data[4], block_data[1], &GroupType, &SubType); + if(ret){ + FM_LOG_WAR(D_RDS,"get group type err[ret=%d]\n", ret); + goto do_next; + } + + ret = rds_group_counter_add(GroupType, SubType, &fm->rds_gc); + + ret = rds_group_pi_get(block_data[4], block_data[0], &pstRDSData->PI, &dirty); + if(ret){ + FM_LOG_WAR(D_RDS,"get group pi err[ret=%d]\n", ret); + goto do_next; + }else if(dirty == TRUE){ + ret = rds_event_set(event, RDS_EVENT_PI_CODE); //yes, we got new PI code + } + + ret = rds_group_pty_get(block_data[4], block_data[1], &pstRDSData->PTY, &dirty); + if(ret){ + FM_LOG_WAR(D_RDS,"get group pty err[ret=%d]\n", ret); + goto do_next; + }else if(dirty == TRUE){ + ret = rds_event_set(event, RDS_EVENT_PTY_CODE); // yes, we got new PTY code + } + + ret = rds_group_tp_get(block_data[4], block_data[1], &pstRDSData->RDSFlag.TP, &dirty); + if(ret){ + FM_LOG_WAR(D_RDS,"get group tp err[ret=%d]\n", ret); + goto do_next; + }else if(dirty == TRUE){ + ret = rds_event_set(event, RDS_EVENT_FLAGS); // yes, we got new TP code + ret = rds_flag_set(flag, RDS_FLAG_IS_TP); + } + + switch(GroupType){ + case 0: + if((ret = MT6620_RDS_RetrieveGroup0(&block_data[0], SubType, pstRDSData))) + goto do_next; + break; + case 1: + if((ret = MT6620_RDS_RetrieveGroup1(&block_data[0], SubType, pstRDSData))) + goto do_next; + break; + case 2: + if((ret = MT6620_RDS_RetrieveGroup2(&block_data[0], SubType, pstRDSData))) + goto do_next; + break; + case 4: + if((ret = MT6620_RDS_RetrieveGroup4(&block_data[0], SubType, pstRDSData))) + goto do_next; + break; + case 14: + if((ret = MT6620_RDS_RetrieveGroup14(&block_data[0], SubType, pstRDSData))) + goto do_next; + break; + default: + break; + } + +do_next: + if(ret && (ret != -ERR_RDS_CRC)){ + FM_LOG_ERR(D_RDS,"parsing err[ret=%d]\n", ret); + return ret; + } + rds_cnt--; + i++; + } + + return ret; +} + diff --git a/drivers/mtk_wcn_combo/drv_wlan/Makefile b/drivers/mtk_wcn_combo/drv_wlan/Makefile new file mode 100755 index 000000000000..20820c11333f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/Makefile @@ -0,0 +1,49 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +obj-$(CONFIG_MTK_COMBO_WIFI) += wlan/ +obj-$(CONFIG_MTK_COMBO_WIFI) += p2p/ +#BUILD_P2P=n + +#ifeq ($(MTK_WIFI_HOTSPOT_SUPPORT), yes) +#BUILD_P2P=y +#endif +#ifeq ($(MTK_WIFI_P2P_SUPPORT), yes) +#BUILD_P2P=y +#endif + +#ifeq ($(BUILD_P2P), y) +#obj-$(CONFIG_MTK_COMBO_WIFI) += p2p/ +#endif diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/Makefile b/drivers/mtk_wcn_combo/drv_wlan/p2p/Makefile new file mode 100755 index 000000000000..a0bd71282a7a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/Makefile @@ -0,0 +1,120 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# --------------------------------------------------- +# Compile Options +# --------------------------------------------------- +ccflags-y += -DLINUX -DMT6620 + +ifeq ($(MTK_WAPI_SUPPORT), yes) + ccflags-y += -DCFG_SUPPORT_WAPI=1 +else + ccflags-y += -DCFG_SUPPORT_WAPI=0 +endif + +ifeq ($(HAVE_XLOG_FEATURE), yes) + ccflags-y += -DCFG_SUPPORT_XLOG=1 +else + ccflags-y += -DCFG_SUPPORT_XLOG=0 +endif + +#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y) +# ccflags-y += -D_HIF_SDIO=1 +#endif +ccflags-y += -D_HIF_SDIO=1 + +#ccflags-y += -DDBG=0 +ccflags-y += -DDBG=0 +ccflags-y += -I$(src)/os -I$(src)/os/linux/include +ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt + +ccflags-y += -I$(src)/../wlan/os -I$(src)/../wlan/os/linux/include -I$(src)/../wlan/os/linux/hif/sdio/include +ccflags-y += -I$(src)/../wlan/include -I$(src)/../wlan/include/nic -I$(src)/../wlan/include/mgmt + +obj-$(CONFIG_MTK_COMBO_WIFI) += p2p.o + +# --------------------------------------------------- +# Directory List +# --------------------------------------------------- +COMMON_DIR := common/ +OS_DIR := os/linux/ +NIC_DIR := nic/ +MGMT_DIR := mgmt/ + +#always := $(shell cp -f ../mediatek/source/kernel/drivers/combo/drv_wlan/wlan/$(OS_DIR)gl_sec.o.new ../mediatek/source/kernel/drivers/combo/drv_wlan/wlan/$(OS_DIR)gl_sec.o) +#always := $(touch ../mediatek/source/kernel/drivers/combo/drv_wlan/wlan/$(OS_DIR)gl_sec.o) + +# --------------------------------------------------- +# 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_fsm.o \ + $(MGMT_DIR)p2p_scan.o \ + $(MGMT_DIR)p2p_rlm.o \ + $(MGMT_DIR)p2p_rlm_obss.o\ + $(MGMT_DIR)p2p_bss.o\ + $(MGMT_DIR)p2p_assoc.o\ + $(MGMT_DIR)p2p_func.o\ + $(MGMT_DIR)p2p_state.o\ + $(MGMT_DIR)p2p_ie.o + +#ifeq ($(MTK_WAPI_SUPPORT), yes) +#MGMT_OBJS += $(MGMT_DIR)wapi.o +#OS_OBJS += $(OS_DIR)gl_sec.o +#endif + +#ifeq ($(WLAN_PROC), y) +#OS_OBJS += gl_proc.o +#endif + +#HIF_OBJS := $(HIF_DIR)arm.o \ +# $(HIF_DIR)sdio.o + +p2p-objs += $(COMMON_OBJS) +p2p-objs += $(NIC_OBJS) +p2p-objs += $(OS_OBJS) +p2p-objs += $(HIF_OBJS) +p2p-objs += $(MGMT_OBJS) + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/common/wlan_p2p.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/common/wlan_p2p.c new file mode 100755 index 000000000000..e69dbb83fe36 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/common/wlan_p2p.c @@ -0,0 +1,1867 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/common/wlan_p2p.c#5 $ +*/ + +/*! \file wlan_bow.c + \brief This file contains the Wi-Fi Direct commands processing routines for + MediaTek Inc. 802.11 Wireless LAN Adapters. +*/ + +/****************************************************************************** +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************* +*/ + +/****************************************************************************** +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************* +*/ + +/* +** $Log: wlan_p2p.c $ + * + * 01 31 2012 yuche.tsai + * NULL + * Fix compile error & del beacon scenario. + * + * 01 26 2012 yuche.tsai + * NULL + * Fix compile warning. + * + * 01 19 2012 chinglan.wang + * NULL + * Support the WPA-PSK TKIP security mode for the tethering. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 Channle 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 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 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 "p2p_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 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(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_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%08lx\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%08lx\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(INIT, 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) ((UINT_32) prNetworkAddress + + (UINT_32) (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) ((UINT_32) prNetworkAddress + + (UINT_32) (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 %ld\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_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(INIT, TRACE, ("\n")); + printk("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) ((UINT_32) prNetworkAddress + + (UINT_32) (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; + + printk("u4IpAddressCount (%ld) \n", (INT_32)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; + printk("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) ((UINT_32) prNetworkAddress + + (UINT_32) (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 %ld\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); + + return wlanoidSendSetQueryP2PCmd(prAdapter, + CMD_ID_MAC_MCAST_ADDR, + TRUE, + FALSE, + FALSE, // This CMD response is no need to complete the OID. Or the event would unsync. + 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 + if ((ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter)) == 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 + if ((ucVersionNum = p2pFuncGetVersionNumOfSD(prAdapter)) == 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_STRUC_T prNoaParam; + CMD_CUSTOM_NOA_PARAM_STRUC_T rCmdNoaParam; + + DEBUGFUNC("wlanoidSetNoaParam"); + DBGLOG(INIT, TRACE,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUC_T)pvSetBuffer; + + kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUC_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_STRUC_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_STRUC_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_STRUC_T prOppPsParam; + CMD_CUSTOM_OPPPS_PARAM_STRUC_T rCmdOppPsParam; + + DEBUGFUNC("wlanoidSetOppPsParam"); + DBGLOG(INIT, TRACE,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUC_T)pvSetBuffer; + + kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUC_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_STRUC_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_STRUC_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_STRUC_T prUapsdParam; + CMD_CUSTOM_UAPSD_PARAM_STRUC_T rCmdUapsdParam; + P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; + P_BSS_INFO_T prBssInfo; + + + DEBUGFUNC("wlanoidSetUApsdParam"); + DBGLOG(INIT, TRACE,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUC_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_STRUC_T)pvSetBuffer; + + kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUC_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_STRUC_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_STRUC_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 */ + +#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 %ld\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/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_assoc.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_assoc.h new file mode 100755 index 000000000000..17450b6965a0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_assoc.h @@ -0,0 +1,104 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/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. +*/ + + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#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/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_bss.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_bss.h new file mode 100755 index 000000000000..c32740e66d0f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_bss.h @@ -0,0 +1,105 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/mgmt/p2p_bss.h#1 $ +*/ + +/*! \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. +*/ + + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_fsm.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_fsm.h new file mode 100755 index 000000000000..d658dc8a973d --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_fsm.h @@ -0,0 +1,2664 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/mgmt/p2p_fsm.h#11 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: p2p_fsm.h $ + * + * 02 24 2012 yuche.tsai + * [ALPS00240756] [WiFi direct]After accept PBC request,DVT pops Kernel Defect.Powering off DVT causes DVT reboots automatcially and pops up KE(once) + * Fix GO dissolving issue to avoid FW assert. + * + * 02 22 2012 yuche.tsai + * [ALPS00240483] [Wifi P2P]Run Sigma tool of A69. Always run fail on 5.1.2. No get correct connection from Realtek. + * Fix assoc response without P2P IE issue for Sigma test. + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 01 27 2012 yuche.tsai + * NULL + * Update for GC connection . + * + * 01 18 2012 yuche.tsai + * NULL + * Add get station info API. + * TX deauth before start beacon. + * + * 01 17 2012 yuche.tsai + * NULL + * Update mgmt frame filter setting. + * Please also update FW 2.1 + * + * 01 16 2012 yuche.tsai + * NULL + * Update Driver for wifi driect gc join IE update issue. + * + * 01 16 2012 yuche.tsai + * NULL + * Add join timer. + * + * 01 16 2012 yuche.tsai + * NULL + * Update P2P driver code for GC Join. + * + * 01 15 2012 yuche.tsai + * NULL + * ICS P2P Driver Update. + * + * 01 15 2012 yuche.tsai + * NULL + * Fix scan bug. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Direct Driver Update for ICS. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 Channle 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. + * + * 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 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Add device discoverability support. (Phase I) + * + * 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. Fix formation policy issue. + * 2. Fix LISTEN channel issue. + * 3. Fix Target IF address in-correct issue when being GO. + * + * 03 21 2011 yuche.tsai + * NULL + * Connection Flow Modification. + * + * 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 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; + + +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 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; + + +/*-------------------- 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; +} 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 +} +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; + +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_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; + +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; + + /* 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; + +}; + + +/*---------------- 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. */ +} MSG_P2P_MGMT_TX_REQUEST_T, *P_MSG_P2P_MGMT_TX_REQUEST_T; + + +typedef struct _MSG_P2P_BEACON_UPDATE_T { + MSG_HDR_T rMsgHdr; + UINT_32 u4DtimPeriod; + UINT_32 u4BcnInterval; + 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_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; + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + + + +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 +p2pFsmRunEventBeaconUpdate( + IN P_ADAPTER_T prAdapter, + IN P_MSG_HDR_T prMsgHdr + ); + + +VOID +p2pFsmRunEventBeaconAbort( + 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 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//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) */ + +/* 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, *P_P2P_ATTRIBUTE_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; /* Prefered 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; + + /* Extened Listen Timing. */ + UINT_16 u2AvailabilityPeriod; + UINT_16 u2AvailabilityInterval; + + UINT_16 u2AttributeLen; + UINT_8 aucAttributesCache[P2P_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; + + UINT_16 u2WscAttributeLen; + UINT_8 aucWscAttributesCache[WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE]; + + UINT_8 aucGroupID[MAC_ADDR_LEN]; + UINT_16 u2GroupSsidLen; + UINT_8 aucGroupSsid[ELEM_MAX_LEN_SSID]; + + PARAM_CUSTOM_NOA_PARAM_STRUC_T rNoaParam; + PARAM_CUSTOM_OPPPS_PARAM_STRUC_T rOppPsParam; + +}; + + + + + + + +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) \ + (_prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eConnectionState = (_eNewMediaState)); + +#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 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) + + + +#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 UINT_32 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. + */ +__KAL_INLINE__ VOID +p2pDataTypeCheck ( + VOID + ) +{ + DATA_STRUC_INSPECTING_ASSERT(sizeof(IE_P2P_T) == (2+4+1)); // all UINT_8 + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRIBUTE_T) == (3+1)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_STATUS_T) == (3+1)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_REASON_T) == (3+1)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CAPABILITY_T) == (3+2)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_ID_T) == (3+6)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GO_INTENT_T) == (3+1)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CFG_TIMEOUT_T) == (3+2)); +#if CID52_53_54 + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3+5)); +#else + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_LISTEN_CHANNEL_T) == (3+5)); +#endif + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_BSSID_T) == (3+6)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_EXT_LISTEN_TIMING_T) == (3+4)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTENDED_IF_ADDR_T) == (3+6)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_MANAGEABILITY_T) == (3+1)); + + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_CHANNEL_T) == (3+4)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(CHANNEL_ENTRY_FIELD_T) == 3); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_NOA_T) == (3+3)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(NOA_DESCRIPTOR_T) == 13); + DATA_STRUC_INSPECTING_ASSERT(sizeof(DEVICE_TYPE_T) == 8); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_DEV_INFO_T) == (3+6+2+8+1+8)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(DEVICE_NAME_TLV_T) == (4+32)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_CLIENT_INFO_DESC_T) == (1+6+6+1+2+8+1+8)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_INFO_T) == (3+(1+6+6+1+2+8+1+8))); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_GROUP_ID_T) == (3+38)); + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_INTERFACE_T) == (3+13)); +#if CID52_53_54 + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3+5)); +#else + DATA_STRUC_INSPECTING_ASSERT(sizeof(P2P_ATTRI_OPERATING_CHANNEL_T) == (3+5)); +#endif + + + return; +} +#endif /* _lint */ + +#endif /* _P2P_FSM_H */ + + + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_func.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_func.h new file mode 100755 index 000000000000..524d100ad457 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_func.h @@ -0,0 +1,284 @@ + + + +#ifndef _P2P_FUNC_H +#define _P2P_FUNC_H + + +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 +p2pFuncGetStationInfo( + IN P_ADAPTER_T prAdapter, + IN PUINT_8 pucMacAddr, + OUT P_P2P_STATION_INFO_T prStaInfo + ); + +P_MSDU_INFO_T +p2pFuncProcessP2pProbeRsp( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMgmtTxMsdu + ); + +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 +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_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 + ); + +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 + ); + +#endif diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_ie.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_ie.h new file mode 100755 index 000000000000..fe0dc1bd3a26 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_ie.h @@ -0,0 +1,28 @@ + + + + + +#ifndef _P2P_IE_H +#define _P2P_IE_H + + +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 + ); + + + +#endif diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm.h new file mode 100755 index 000000000000..5f1a02cb173e --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm.h @@ -0,0 +1,149 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/mgmt/p2p_rlm.h#1 $ +*/ + +/*! \file "rlm.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm_obss.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm_obss.h new file mode 100755 index 000000000000..2773c152d7e9 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_rlm_obss.h @@ -0,0 +1,133 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/mgmt/p2p_rlm_obss.h#1 $ +*/ + +/*! \file "rlm_obss.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#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/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_scan.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_scan.h new file mode 100755 index 000000000000..96a306378245 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_scan.h @@ -0,0 +1,167 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/mgmt/p2p_scan.h#2 $ +*/ + +/*! \file "scan.h" + \brief + +*/ + + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#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/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_state.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_state.h new file mode 100755 index 000000000000..0fccdcdcb14c --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/mgmt/p2p_state.h @@ -0,0 +1,88 @@ + +#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_P2P_FSM_INFO_T prP2pFsmInfo + ); + +VOID +p2pStateAbort_CHNL_ON_HAND( + IN P_ADAPTER_T prAdapter, + IN P_P2P_FSM_INFO_T prP2pFsmInfo, + 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/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p.h new file mode 100755 index 000000000000..c63fae0a9930 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p.h @@ -0,0 +1,235 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/nic/p2p.h#1 $ +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: p2p.h $ + * + * 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. + * + * 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/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_cmd_buf.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_cmd_buf.h new file mode 100755 index 000000000000..cd91f339b59a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_cmd_buf.h @@ -0,0 +1,137 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: p2p_cmd_buf.h $ + * + * 11 24 2011 yuche.tsai + * NULL + * Fix P2P IOCTL of multicast address bug, add low power driver stop control. + * + * 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. + * + * 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/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_mac.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_mac.h new file mode 100755 index 000000000000..e52e8da45205 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_mac.h @@ -0,0 +1,263 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/nic/p2p_mac.h#1 $ +*/ + +/*! \file "p2p_mac.h" + \brief Brief description. + + Detail description. +*/ + + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic.h new file mode 100755 index 000000000000..67ec009dc44b --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic.h @@ -0,0 +1,114 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/nic/p2p_nic.h#1 $ +*/ + +/*! \file "p2p_nic.h" + \brief The declaration of nic functions + + Detail description. +*/ + + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic_cmd_event.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic_cmd_event.h new file mode 100755 index 000000000000..e80a69ad8c00 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/nic/p2p_nic_cmd_event.h @@ -0,0 +1,113 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/nic/p2p_nic_cmd_event.h#1 $ +*/ + +/*! \file p2p_nic_cmd_event.h + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#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 \ No newline at end of file diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/include/p2p_precomp.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/p2p_precomp.h new file mode 100755 index 000000000000..b5f0de652798 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/p2p_precomp.h @@ -0,0 +1,265 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/include/p2p_precomp.h#4 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +#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" +#elif defined(MT5931) + #include "mt5931_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/mtk_wcn_combo/drv_wlan/p2p/include/wlan_p2p.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/wlan_p2p.h new file mode 100755 index 000000000000..c725a0d4e6d1 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/include/wlan_p2p.h @@ -0,0 +1,454 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: wlan_p2p.h $ + * + * 02 23 2012 chinglan.wang + * [ALPS00240621] [Wifi P2P]Run Sigma tool of A69. Always run fail on 7.1.3. sniffer check Sta-IsActive-No-Frames-With-PowerMgmt-1 + * . + * + * 01 17 2012 wh.su + * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting + * adding the code to fix the add key function. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 Channle 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 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 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; + +#if CONFIG_NL80211_TESTMODE + +typedef struct _NL80211_DRIVER_TEST_PARAMS { + UINT_16 idx_mode; + UINT_16 idx; + UINT_32 value; +} NL80211_DRIVER_TEST_PARAMS, *P_NL80211_DRIVER_TEST_PARAMS; + +#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 +******************************************************************************** +*/ + +/*--------------------------------------------------------------*/ +/* 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 + ); + +#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/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_assoc.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_assoc.c new file mode 100755 index 000000000000..4f20f5caf0d4 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_assoc.c @@ -0,0 +1,139 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E 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 "p2p_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/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_bss.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_bss.c new file mode 100755 index 000000000000..bde305b3f704 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_bss.c @@ -0,0 +1,125 @@ +/* +** $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. +*/ + + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E 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 "p2p_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 +******************************************************************************** +*/ + +APPEND_VAR_IE_ENTRY_T txProbRspIETableWIP2P[] = { + { (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL, bssGenerateExtSuppRate_IE } /* 50 */ + ,{ (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_OBSS_SCAN), NULL, rlmRspGenerateObssScanIE } /* 74 */ + ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE } /* 127 */ + ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE } /* 48 */ + ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWpaNoneIE } /* 221 */ + ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE } /* 221 */ +}; + + +/******************************************************************************* +* M A 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 +******************************************************************************** +*/ + +UINT_32 +p2pGetTxProbRspIeTableSize( + VOID + ) +{ + return (sizeof(txProbRspIETableWIP2P)/sizeof(APPEND_VAR_IE_ENTRY_T)); +} + + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_fsm.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_fsm.c new file mode 100755 index 000000000000..2dbf121a30d4 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_fsm.c @@ -0,0 +1,3155 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/mgmt/p2p_fsm.c#24 $ +*/ + +/*! \file "p2p_fsm.c" + \brief This file defines the FSM for P2P Module. + + This file defines the FSM for P2P Module. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: p2p_fsm.c $ + * + * 02 24 2012 yuche.tsai + * [ALPS00240756] [WiFi direct]After accept PBC request,DVT pops Kernel Defect.Powering off DVT causes DVT reboots automatcially and pops up KE(once) + * Fix GO dissolving issue to avoid FW assert. + * + * 02 22 2012 yuche.tsai + * [ALPS00240483] [Wifi P2P]Run Sigma tool of A69. Always run fail on 5.1.2. No get correct connection from Realtek. + * Fix assoc response without P2P IE issue for Sigma test. + * + * 02 21 2012 yuche.tsai + * [ALPS00240187] [WiFi direct]When turn on WiFi Direct,phone reboots automatically and KE(KERNEL-PANIC) pos up + * Add driver pointer check to avoid KE in wifi direct driver. + * + * 02 15 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Fix P2P response rate issue under P2P device mode. + * + * 02 09 2012 yuche.tsai + * [ALPS00233018] [klocwork 9.1] in p2p_fsm.c, line 1633 + * After fix error. + * + * 02 09 2012 yuche.tsai + * [ALPS00233018] [klocwork 9.1] in p2p_fsm.c, line 1633 + * Before fix error. + * + * 02 08 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Try to fix clockwork warning. + * + * 02 06 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Small bug fix for CNM memory usage, scan SSID search issue, P2P network deactivate issue. + * + * 02 02 2012 yuche.tsai + * NULL + * Big fix. + * + * 01 31 2012 yuche.tsai + * NULL + * Fix compile error & del beacon scenario. + * + * 01 27 2012 yuche.tsai + * NULL + * Update for GC connection . + * + * 01 26 2012 yuche.tsai + * NULL + * Fix compile warning. + * + * 01 20 2012 yuche.tsai + * NULL + * Update for RX probe request. + * + * 01 19 2012 yuche.tsai + * NULL + * Update WiFi Direct RX probe request issue. + * + * 01 19 2012 yuche.tsai + * NULL + * Fix scan p2p IE issue. + * + * 01 18 2012 yuche.tsai + * NULL + * Bug fix for memory allocation. + * + * 01 18 2012 yuche.tsai + * NULL + * Fix bug of BSS info indication. + * + * 01 18 2012 yuche.tsai + * NULL + * Add get station info API. + * TX deauth before start beacon. + * + * 01 17 2012 yuche.tsai + * NULL + * Update mgmt frame filter setting. + * Please also update FW 2.1 + * + * 01 16 2012 yuche.tsai + * NULL + * Update Driver for wifi driect gc join IE update issue. + * + * 01 16 2012 yuche.tsai + * NULL + * Add join timer. + * + * 01 16 2012 yuche.tsai + * NULL + * Update P2P driver code for GC Join. + * + * 01 15 2012 yuche.tsai + * NULL + * ICS P2P Driver Update. + * + * 01 15 2012 yuche.tsai + * NULL + * Fix scan bug. + * + * 01 13 2012 yuche.tsai + * NULL + * Update WiFi tethering driver for ICS. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Direct Driver Update for ICS. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 + * [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. + * + * 07 05 2011 yuche.tsai + * [WCXRP00000833] [Volunteer Patch][WiFi Direct][Driver] Service Discovery Frame RX Indicate Issue + * Solve Service Discovery Response Race Condition issue. + * + * 06 28 2011 yuche.tsai + * [WCXRP00000820] [Volunteer Patch][MT6620][WiFi Direct][Driver] GO can not connect to the third device issue + * Fix GO can not activly connect to the third P2P device issue. + * + * 06 23 2011 cp.wu + * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module + * follow-ups for frequency-shifted WAPI AP support + * + * 06 22 2011 yuche.tsai + * [WCXRP00000808] [Volunteer Patch][MT6620][Driver/FW] Device discoverability issue fix + * Fix some device discoverability issue. + * + * 06 21 2011 yuche.tsai + * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. + * Fix some 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 + * [WCXRP00000799] [Volunteer Patch][MT6620][Driver] Connection Indication Twice Issue. + * Fix connection indication twice issue. + * + * 06 20 2011 yuche.tsai + * [WCXRP00000796] [Volunteer Patch][MT6620][Driver] Add BC deauth frame TX feature. + * Add feature to send BC deauth frame when under AP/GO mode. + * + * 06 20 2011 yuche.tsai + * [WCXRP00000795] [Volunteer Patch][MT6620][Driver] GO can not connect second device issue + * Solve GO can not formation with second device issue. + * + * 06 14 2011 yuche.tsai + * NULL + * Add compile flag to disable persistent group support. + * + * 06 10 2011 yuche.tsai + * [WCXRP00000776] [Need Patch][MT6620][Driver] MT6620 response probe request of P2P device with P2P IE under Hot Spot mode. + * Driver should not reponse probe request of P2P device under Hot Spot mode. + * + * 06 10 2011 yuche.tsai + * [WCXRP00000775] [Volunteer Patch][MT6620][Driver] Dynamic enable SD capability + * Support Dynamic enable SD capability. + * + * 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] + * Accept other p2p device connection if the original one is lost. + * + * 05 18 2011 yuche.tsai + * NULL + * Fix compile error. A new feature would not be included in v2.0 p2p driver + * + * 05 18 2011 yuche.tsai + * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. + * A solution for both connection request & iocontrol request. + * + * 05 17 2011 yuche.tsai + * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. + * The solution has some issue, still working. + * + * 05 16 2011 yuche.tsai + * [WCXRP00000728] [Volunteer Patch][MT6620][Driver] Service Discovery Request TX issue. + * Fix SD Request can not TX 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 BSS descriptor is found first before p2p descriptor. + * + * 05 04 2011 yuche.tsai + * [WCXRP00000696] [Volunteer Patch][MT6620][Driver] Infinite loop issue when RX invitation response. + * Add an end condition in while loop of invitation response frame checking function. + * + * 05 02 2011 yuche.tsai + * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout. + * Clear flag after Tx lifetime timeout of GO NEGO frame. + * + * 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 + * NULL + * 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 only has Password ID instead of Configure method. + * + * 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. + * Refine P2P connection flow for Sigma Test.. + * + * 04 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Add device discoverability support. (Phase I) + * + * 03 28 2011 yuche.tsai + * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. + * 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 sync station state to FW. + * + * 03 23 2011 yuche.tsai + * NULL + * Fix Response Rate Issue when TX Auth Rsp Frame under P2P Mode.. + * + * 03 23 2011 yuche.tsai + * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct. + * Fix issue of connection to one GC.. + * + * 03 23 2011 yuche.tsai + * NULL + * Fix ASSERT issue under Hot-Spot mode. + * + * 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 GO. + * + * 03 22 2011 yuche.tsai + * NULL + * 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. Fix formation policy issue. + * 2. Fix LISTEN channel issue. + * 3. Fix Target IF address in-correct issue when being GO. + * + * 03 21 2011 yuche.tsai + * NULL + * Connection Flow Modification. + * + * 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 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 continous 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 "p2p_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 */ +#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)); + + prP2pFsmInfo->eCurrentState = prP2pFsmInfo->ePreviousState = P2P_STATE_IDLE; + prP2pFsmInfo->prTargetBss = NULL; + + cnmTimerInitTimer(prAdapter, + &(prP2pFsmInfo->rP2pFsmTimeoutTimer), + (PFN_MGMT_TIMEOUT_FUNC)p2pFsmRunEventFsmTimeout, + (UINT_32)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; + } + + + } while (FALSE); + + return; +} /* 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]); + + p2pFsmRunEventAbort(prAdapter, prP2pFsmInfo); + + p2pFuncSwitchOPMode(prAdapter, prP2pBssInfo, OP_MODE_P2P_DEVICE, TRUE); + + UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX); + + wlanAcquirePowerControl(prAdapter); + + /* Release all pending CMD queue. */ + wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue); + + wlanReleasePowerControl(prAdapter); + + /* Clear PendingCmdQue*/ + wlanReleasePendingCMDbyNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); + + if (prP2pBssInfo->prBeacon) { + nicTxReturnMsduInfo(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)); + DBGLOG(P2P, STATE, ("p2pFsmStateTransition \n")); + prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); + prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; + + if (!IS_BSS_ACTIVE(prP2pBssInfo)) { + SET_NET_ACTIVE(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])); +#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, eNextState); + } + else { + // Initial channel ready. + // Send channel ready event. + // Start a FSM timer. + p2pStateInit_CHNL_ON_HAND(prAdapter, prP2pFsmInfo); + } + + break; + case P2P_STATE_GC_JOIN: + if (fgIsTransOut) { + + // Join complete / join canceled. + p2pStateAbort_GC_JOIN(prAdapter, + prP2pFsmInfo, + &(prP2pFsmInfo->rJoinInfo), + eNextState); + } + else { + ASSERT(prP2pFsmInfo->prTargetBss != NULL); + + // 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; + 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) { + + if ((prP2pFsmInfo->prTargetBss = p2pFuncKeepOnConnection(prAdapter, + &prP2pFsmInfo->rConnReqInfo, + &prP2pFsmInfo->rChnlReqInfo, + &prP2pFsmInfo->rScanReqInfo)) == 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); + } + + return; +} /* 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; + 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); + } + } 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; + 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); + + prChnlReqInfo->u8Cookie = prP2pChnlReqMsg->u8Cookie; /* Cookie can only be assign after abort.(for indication) */ + 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; + } + +#if 1 + prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].ucPrimaryChannel = prP2pChnlReqMsg->rChannelInfo.ucChannelNum; + prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX].eBand = prP2pChnlReqMsg->rChannelInfo.eBand; + +#endif + + p2pFsmStateTransition(prAdapter, prP2pFsmInfo, eNextState); + + } while (FALSE); + + + if (prMsgHdr) { + cnmMemFree(prAdapter, prMsgHdr); + } + + return; +} /* 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; + prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; + + DBGLOG(P2P, TRACE, ("p2pFsmRunEventChannelAbort\n")); + + if ((prChnlAbortMsg->u8Cookie == prChnlReqInfo->u8Cookie) && + (prChnlReqInfo->fgIsChannelRequested)) { + + DBGLOG(P2P, TRACE, ("prP2pFsmInfo->eCurrentState:%d \n", + prP2pFsmInfo->eCurrentState)); + + 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); + } + + return; +} /* 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; + 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); + } + + return; +} /* p2pFsmRunEventScanAbort */ + + + + + +VOID +p2pFsmRunEventAbort ( + IN P_ADAPTER_T prAdapter, + IN P_P2P_FSM_INFO_T prP2pFsmInfo + ) +{ + do { + ASSERT_BREAK((prAdapter != NULL) && (prP2pFsmInfo != NULL)); + + 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; + } + // For other state, is there any special action that should be take before leaving? + + p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); + } + else { + P_P2P_CHNL_REQ_INFO_T prChnlReqInfo = &(prP2pFsmInfo->rChnlReqInfo); + + if (prChnlReqInfo->fgIsChannelRequested) { + cnmTimerStopTimer(prAdapter, &(prP2pFsmInfo->rP2pFsmTimeoutTimer)); + } + } + + + } while (FALSE); + + return; +} /* 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 UINT_32 u4Param + ) +{ + P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)u4Param; + + 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); + } + } + 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: + { + p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); + } + break; +// case P2P_STATE_GC_JOIN: +// break; + default: + break; + } + + } while (FALSE); + + return; +} /* 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; + 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 +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; + DBGLOG(P2P, TRACE, ("p2pFsmRunEventBeaconUpdate 0001\n")); + prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]); + DBGLOG(P2P, TRACE, ("p2pFsmRunEventBeaconUpdate 0002\n")); + prBcnUpdateMsg = (P_MSG_P2P_BEACON_UPDATE_T)prMsgHdr; + DBGLOG(P2P, TRACE, ("p2pFsmRunEventBeaconUpdate 0003\n")); + if (prBcnUpdateMsg->u4BcnInterval) { + DBGLOG(P2P, TRACE, ("Beacon interval updated to :%ld \n", prBcnUpdateMsg->u4BcnInterval)); + prP2pBssInfo->u2BeaconInterval = (UINT_16)prBcnUpdateMsg->u4BcnInterval; + } + else if (prP2pBssInfo->u2BeaconInterval == 0) { + prP2pBssInfo->u2BeaconInterval = DOT11_BEACON_PERIOD_DEFAULT; + } + if (prBcnUpdateMsg->u4DtimPeriod) { + DBGLOG(P2P, TRACE, ("DTIM interval updated to :%ld \n", prBcnUpdateMsg->u4DtimPeriod)); + prP2pBssInfo->ucDTIMPeriod = (UINT_8)prBcnUpdateMsg->u4DtimPeriod; + } + else if (prP2pBssInfo->ucDTIMPeriod == 0) { + prP2pBssInfo->ucDTIMPeriod = DOT11_DTIM_PERIOD_DEFAULT; + } + DBGLOG(P2P, TRACE, ("p2pFsmRunEventBeaconUpdate 0004\n")); + p2pFuncBeaconUpdate(prAdapter, + prP2pBssInfo, + &prP2pFsmInfo->rBcnContentInfo, + prBcnUpdateMsg->pucBcnHdr, + prBcnUpdateMsg->u4BcnHdrLen, + prBcnUpdateMsg->pucBcnBody, + prBcnUpdateMsg->u4BcnBodyLen); + DBGLOG(P2P, TRACE, ("p2pFsmRunEventBeaconUpdate 0005\n")); + + if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) && + (prP2pBssInfo->eIntendOPMode == OP_MODE_NUM)) { + /* AP is created, Beacon Update. */ + nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX); + + nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); + DBGLOG(P2P, TRACE, ("AP is created, Beacon Update\n")); + } + else { + 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); + } + + // 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. */ + /* Becuase 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; + } + /* 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); + } + +} /* p2pFsmRunEventBeaconUpdate */ + + +VOID +p2pFsmRunEventBeaconAbort ( + 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, ("p2pFsmRunEventBeaconAbort\n")); + + if ((prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { + /* AP is created, Beacon Update. */ + 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); + + } while (FALSE); + + if (prMsgHdr) { + cnmMemFree(prAdapter, prMsgHdr); + } + +} /* p2pFsmRunEventBeaconAbort */ + +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; + 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; + } + // 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); + + 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; + + 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; + + do { + + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + + DBGLOG(P2P, TRACE, ("p2pFsmRunEventConnectionAbort: Connection Abort.\n")); + + prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; + 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; + + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, NULL, NULL, 0, 0); + + 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 ["MACSTR":"MACSTR"]\n", + MAC2STR(prP2pBssInfo->prStaRecOfAP->aucMacAddr), + MAC2STR(prDisconnMsg->aucTargetID))); + break; + } + + /* Stop rejoin timer if it is started. */ + // TODO: If it has. + + p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, prDisconnMsg->fgSendDeauth, prDisconnMsg->u2ReasonCode); + + } + 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: "MACSTR"\n", MAC2STR(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: "MACSTR"\n", MAC2STR(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); + + break; + } + } + + } + break; + case OP_MODE_P2P_DEVICE: + default: + ASSERT(FALSE); + break; + } + + } while (FALSE); + + if (prMsgHdr) { + cnmMemFree(prAdapter, prMsgHdr); + } + + return; +} /* 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); + } + + return; +} +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, TRACE, ("Deauth TX Done\n")); + + 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); + + 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); + } + + + } 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, TRACE, ("Mgmt Frame TX Fail, Status:%d.\n", rTxDoneStatus)); + } + 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; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMsgHdr != NULL)); + + DBGLOG(P2P, TRACE, ("P2P Join Complete\n")); + + prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; + prJoinInfo = &(prP2pFsmInfo->rJoinInfo); + 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); + } + + //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); + +#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); + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + &prP2pFsmInfo->rConnReqInfo, + prJoinInfo->aucIEBuf, + prJoinInfo->u4BufLength, + prStaRec->u2StatusCode); + + } + 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; + + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + &prP2pFsmInfo->rConnReqInfo, + prJoinInfo->aucIEBuf, + prJoinInfo->u4BufLength, + prStaRec->u2StatusCode); + + } + + } + } + } + + if (prAssocRspSwRfb) { + nicRxReturnRFB(prAdapter, prAssocRspSwRfb); + } + + if (prP2pFsmInfo->eCurrentState == P2P_STATE_GC_JOIN) { + /* Return to IDLE state. */ + p2pFsmStateTransition(prAdapter, prP2pFsmInfo, P2P_STATE_IDLE); + } + + } while (FALSE); + + if (prMsgHdr) { + cnmMemFree(prAdapter, prMsgHdr); + } + + return; + +} /* 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; + + 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 */ + + + + +#if 0 +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#endif + + + + + + + +/*----------------------------------------------------------------------------*/ +/*! +* \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_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); + } + + + 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; + + 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); + + p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); + } + 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. */ + 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); + + + return; +} /* 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; + UINT_16 u2ReasonCode = 0; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); + + if (prStaRec == NULL) { + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + } + + + 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); + + u2IELength = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN + REASON_CODE_FIELD_LEN); + + /* Indicate disconnect to Host. */ + kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, + NULL, + prDisassocFrame->aucInfoElem, + u2IELength, + prStaRec->u2ReasonCode); + } + 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. */ + p2pFuncDisconnect(prAdapter, prStaRec, FALSE, u2ReasonCode); + + break; + } + } + } + break; + case OP_MODE_P2P_DEVICE: + default: + ASSERT(FALSE); + break; + } + + + } while (FALSE); + + return; +} /* 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); + + return; +} /* 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); + + if (prP2pBssInfo->prStaRecOfAP != NULL) { + p2pFuncDisconnect(prAdapter, prP2pBssInfo->prStaRecOfAP, FALSE, REASON_CODE_DISASSOC_INACTIVITY); + } + } + } while (FALSE); + + return; +} /* p2pFsmRunEventBeaconTimeout */ + + + + + + + + + + +/*----------------------------------------------------------------------------*/ +/*! +* @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 (IS_STA_P2P_TYPE(prStaRec)) { + // 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 indiate 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]); + + p2pFuncDisconnect(prAdapter, prStaRec, FALSE, REASON_CODE_UNSPECIFIED); + + bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); + + return; +} /* p2pRunEventAAATxFail */ + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indiate 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; + + bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec); + + if (prP2pBssInfo->rStaRecOfClientList.u4NumElem >= P2P_MAXIMUM_CLIENT_COUNT) { + rStatus = WLAN_STATUS_RESOURCES; + break; + } + + bssAddStaRecToClientList(prAdapter, prP2pBssInfo, prStaRec); + + prStaRec->u2AssocId = bssAssignAssocID(prStaRec); + + 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 indiate 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; + + + 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/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_func.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_func.c new file mode 100755 index 000000000000..67defd59bda0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_func.c @@ -0,0 +1,2940 @@ +#include "p2p_precomp.h" + +APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = { + { (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS) , NULL, p2pFuncAppendAttriStatusForAssocRsp } /* 0 */ // Status + ,{ (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 prefered 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; + + DEBUGFUNC("p2pFuncRequestScan()"); + DBGLOG(P2P, TRACE, ("p2pFuncRequestScan() \n")); + + 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. */ + 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; + + 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; + } + case SCAN_CHANNEL_FULL: + case SCAN_CHANNEL_2G4: + 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; + } + DBGLOG(P2P, TRACE, ("p2pFuncRequestScan():set prScanReq \n")); + } + 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); + + return; +} /* 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); + + return; +} /* p2pFuncCancelScan */ + + +VOID +p2pFuncSwitchOPMode ( + IN P_ADAPTER_T prAdapter, + IN P_BSS_INFO_T prP2pBssInfo, + IN ENUM_OP_MODE_T eOpMode, + IN BOOLEAN fgSyncToFW + ) +{ + 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); + + p2pFsmRunEventBeaconAbort(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); + } + + /* Change interface address. */ + if (eOpMode == OP_MODE_ACCESS_POINT) { + DBGLOG(P2P, TRACE, ("p2pFuncSwitchOPMode: Switch to AP.\n")); + } + + 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); + } + + 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); + } + 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 " MACSTR " \n", MAC2STR(prP2pBssInfo->aucOwnMacAddr))); + DBGLOG(P2P, TRACE, ("The BSSID is changed to " MACSTR " \n", MAC2STR(prP2pBssInfo->aucBSSID))); + + /* Update BSS INFO to FW. */ + if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) { + nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX); + DBGLOG(P2P, TRACE, ("Update BSS INFO to FW in nicUpdateBss \n")); + } + } + + } while (FALSE); + + return; +} /* 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); + + DBGLOG(P2P, TRACE, ("p2pFuncStartGO:\n")); + + /* 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 (fgIsPureAP) { + if (prBssInfo->eBand == BAND_5G) { + prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN); /* Depend on eBand */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + } + else { + prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN); /* Depend on eBand */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + } + } + else { + prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN); /* Depend on eBand */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + } + + + 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> Setup BSSID + nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX); + + } while (FALSE); + + return; +} /* 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; + } + else { + 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); + + return; +} /* 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; + 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); + + return; +} /* 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; + UINT_8 aucIEBuf[MAX_IE_LENGTH]; + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate \n")); + + do { + ASSERT_BREAK((prAdapter != NULL) && + (prP2pBssInfo != NULL) && + (prBcnUpdateInfo != NULL)); + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0001 \n")); + prBcnMsduInfo = prP2pBssInfo->prBeacon; +#if DBG + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0001.1 \n")); + if (prBcnUpdateInfo->pucBcnHdr != NULL) { + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0001.2 \n")); + ASSERT((UINT_32)prBcnUpdateInfo->pucBcnHdr == ((UINT_32)prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD)); + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0001.3 \n")); + } + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0002 \n")); + if (prBcnUpdateInfo->pucBcnBody != NULL) { + ASSERT((UINT_32)prBcnUpdateInfo->pucBcnBody == ((UINT_32)prBcnUpdateInfo->pucBcnHdr + (UINT_32)prBcnUpdateInfo->u4BcnHdrLen)); + } +#endif + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0003 \n")); + + + prBcnFrame = (P_WLAN_BEACON_FRAME_T)((UINT_32)prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD); + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0004 \n")); + if (!pucNewBcnBody) { + /* Old body. */ + pucNewBcnBody = prBcnUpdateInfo->pucBcnBody; + ASSERT(u4NewBodyLen == 0); + u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen; + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0005-1 \n")); + } + else { + prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen; + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0005-2 \n")); + } + + /* Temp buffer body part. */ + kalMemCopy(aucIEBuf, pucNewBcnBody, u4NewBodyLen); + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0006 \n")); + if (pucNewBcnHdr) { + kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen); + prBcnUpdateInfo->pucBcnHdr = (PUINT_8)prBcnFrame; + prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen; + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0007 \n")); + } + + pucIEBuf = (PUINT_8)((UINT_32)prBcnUpdateInfo->pucBcnHdr + (UINT_32)prBcnUpdateInfo->u4BcnHdrLen); + kalMemCopy(pucIEBuf, aucIEBuf, u4NewBodyLen); + prBcnUpdateInfo->pucBcnBody = pucIEBuf; + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0008 \n")); + /* Frame Length */ + prBcnMsduInfo->u2FrameLength = (UINT_16)(prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen); + + prBcnMsduInfo->ucPacketType = 3; + prBcnMsduInfo->fgIs802_11 = TRUE; + prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX; + + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0009 \n")); + /* Update BSS INFO related information. */ + COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr); + COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID); + prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo; + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0010 \n")); + p2pFuncParseBeaconContent(prAdapter, + prP2pBssInfo, + (PUINT_8)prBcnFrame->aucInfoElem, + (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem))); + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0011 \n")); +#if 1 + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0012 \n")); + 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 + DBGLOG(P2P, TRACE, ("p2pFuncBeaconUpdate: 0013 \n")); + } 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 ((UINT_32)prCliStaRec == (UINT_32)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; + } + 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 ((UINT_32)prCliStaRec == (UINT_32)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; + } + fgIsStaFound = TRUE; + break; + default: + break; + } + + if (fgIsStaFound) { + if (fgSendDisassoc) { + assocSendDisAssocFrame(prAdapter, prCliStaRec, u2ReasonCode); + } + + p2pFuncDisconnect(prAdapter, prCliStaRec, FALSE, u2ReasonCode); + + } + + 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) { + // 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL. + p2pFuncDisconnect(prAdapter, + prP2pBssInfo->prStaRecOfAP, + fgSendDeauth, + u2ReasonCode); + } + + 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); + + p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode); + + } + + } + + 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); + + return; +} /* 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; + + DBGLOG(P2P, TRACE, ("p2pFuncDisconnect()")); + + 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); + + 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); + + 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 */ + + + + + + +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; + + do { + ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL)); + + if (prMgmtTxReqInfo->fgIsMgmtTxRequested) { + + // 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL + /* Packet on driver, not done yet, drop it. */ + if ((prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu) != 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; + } + + // 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)((UINT_32)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: + 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); + 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; + + 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); + + return; +} +/* 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 + + return; +} /* 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, TRACE, ("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) { + /* 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); + + 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) { + /* GROUP limit full. */ + /* P2P 3.2.8 */ + DBGLOG(P2P, WARN, ("Group Limit Full. (%d)\n", (INT_16)prP2pBssInfo->rStaRecOfClientList.u4NumElem)); + cnmStaRecFree(prAdapter, prStaRec, FALSE); + break; + } + else { + // TODO: /* Black List. */ + } + + //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); + + return; +} /* 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; + + ASSERT(prP2PConnSettings); + + /* 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; + + return; +} /* 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; + + /* 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; + } + else { + 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; + } + + *pu2StatusCode = STATUS_CODE_SUCCESSFUL; + + } while (FALSE); + + 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"); + + do { + + ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL)); + + prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo; + + if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) { + /* 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) { + 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; + BOOL ucNewSecMode = FALSE; + BOOL ucOldSecMode = FALSE; + + 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")); + + /* Update when starting GO. */ + 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:%lx, 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")); + { + UINT_8 ucOuiType; + UINT_16 u2SubTypeVersion; + if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) { + if ((ucOuiType == VENDOR_OUI_TYPE_WPA) && + (u2SubTypeVersion == VERSION_WPA)) { + kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP); + ucNewSecMode = TRUE; + } + 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 { + + 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); + + return; +} /* 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); + + + return; +} /* 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%lx\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); + + return; +} /* p2pFuncMgmtFrameRegister */ + + +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); + + return; +} /* p2pFuncGetStationInfo */ + +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; + + + 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)((UINT_32)prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD); + ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP); + + //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; + 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: + { + UINT_8 ucOuiType = 0; + UINT_16 u2SubTypeVersion = 0; + 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; + } + + } + + } + 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); + } + + + + + if ((u2EstimateSize += u2EstimatedExtraIELen) > (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)((UINT_32)(prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD), + prProbeRspFrame->aucDestAddr, + prProbeRspFrame->aucSrcAddr, + prProbeRspFrame->aucBSSID, + prProbeRspFrame->u2BeaconInterval, + 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)((UINT_32)prRetMsduInfo->prPacket + (UINT_32)prRetMsduInfo->u2FrameLength)); + + prRetMsduInfo->u2FrameLength += (UINT_16)kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2); + } + + if (fgIsP2PIE) { + kalP2PGenWSC_IE(prAdapter->prGlueInfo, + 1, + (PUINT_8)((UINT_32)prRetMsduInfo->prPacket + (UINT_32)prRetMsduInfo->u2FrameLength)); + + prRetMsduInfo->u2FrameLength += (UINT_16)kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1); + } + + + } +while (FALSE); + + if (prRetMsduInfo != prMgmtTxMsdu) { + cnmMgtPktFree(prAdapter, prMgmtTxMsdu); + } + + + return prRetMsduInfo; +} /* p2pFuncProcessP2pProbeRsp */ + +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)); + + 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)); + + prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo; + + pucIEBuf = (PUINT_8)((UINT_32)prMsduInfo->prPacket + (UINT_32)prMsduInfo->u2FrameLength); + + kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen); + + prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen; + + } while (FALSE); + + return; +} /* p2pFuncGenerateP2p_IEForBeacon */ + + +/*----------------------------------------------------------------------------*/ +/*! +* @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 (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_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)((UINT_32)prMsduInfo->prPacket + + (UINT_32)prMsduInfo->u2FrameLength); + + ASSERT(pucBuffer); + + // TODO: Check P2P FSM State. + kalP2PGenWSC_IE(prAdapter->prGlueInfo, + 0, + pucBuffer); + + prMsduInfo->u2FrameLength += u2IELen; + + return; +} /* p2pFuncGenerateP2p_IEForBeacon */ + +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)((UINT_32)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)((UINT_32)prIeP2P + (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)); + + prIeP2P = (P_IE_P2P_T)((UINT_32)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); + + return; +} /* 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)((UINT_32)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)((UINT_32)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 */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_ie.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_ie.c new file mode 100755 index 000000000000..8d85f7504511 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_ie.c @@ -0,0 +1,73 @@ + +#include "p2p_precomp.h" + + + +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; + + } +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)((UINT_32)prMsduInfo->prPacket + (UINT_32)prMsduInfo->u2FrameLength); + + kalMemCopy(pucIEBuf, prConnReqInfo->aucIEBuf, prConnReqInfo->u4BufLength); + + prMsduInfo->u2FrameLength += prConnReqInfo->u4BufLength; + + } while (FALSE); + + return; + +} /* p2pGenerate_IEForAssocReq */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm.c new file mode 100755 index 000000000000..913429d20dba --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm.c @@ -0,0 +1,1048 @@ +/* +** $Id: @(#) p2p_rlm.c@@ +*/ + +/*! \file "p2p_rlm.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E 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 "p2p_precomp.h" + +extern VOID +rlmSyncOperationParams ( + P_ADAPTER_T prAdapter, + P_BSS_INFO_T prBssInfo + ); + +/******************************************************************************* +* 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; + + 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->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 */ + if (eHtProtectMode == HT_PROTECT_MODE_NONE) { + 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); + } + } + + /* 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 + prChannelEntryField->ucNumberOfChannels)) { + /* 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 + } + + ucBufferSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryField->ucNumberOfChannels); + + prChannelEntryField = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryField + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (UINT_32)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 deivce 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 + return; +} /* 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]; + 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)((UINT_32)prChannelEntryIII + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (UINT_32)prChannelEntryIII->ucNumberOfChannels); + } + + ucOriChnlSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryI->ucNumberOfChannels); + + prChannelEntryI = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryI + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (UINT_32)prChannelEntryI->ucNumberOfChannels); + + + } + + + ucChannelListSize -= (P2P_ATTRI_LEN_CHANNEL_ENTRY + prChannelEntryII->ucNumberOfChannels); + + prChannelEntryII = (P_CHANNEL_ENTRY_FIELD_T)((UINT_32)prChannelEntryII + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (UINT_32)prChannelEntryII->ucNumberOfChannels); + + + } + + + kalMemCopy(prP2pConnSetting->aucChannelEntriesField, aucCommonChannelList, ucNewChnlSize); + prP2pConnSetting->ucRfChannelListSize = ucNewChnlSize; + + } while (FALSE); + + return; +} /* 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 + } + 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); + } + + } + + + } 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)((UINT_32)prChannelEntry + + P2P_ATTRI_LEN_CHANNEL_ENTRY + + (UINT_32)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/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm_obss.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm_obss.c new file mode 100755 index 000000000000..f4ada2e6f27e --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_rlm_obss.c @@ -0,0 +1,414 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E 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 "p2p_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/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_scan.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_scan.c new file mode 100755 index 000000000000..0d7337286127 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_scan.c @@ -0,0 +1,865 @@ +/* +** $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. +*/ + + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E 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 "p2p_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; + } + } + + return; +} /* 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)); + } + } + + return; +} /* 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 + ) +{ + 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; + + if (prBssDesc->fgIsP2PPresent) { + + if ((!prP2pBssInfo->ucDTIMPeriod) && // First time. + (prP2pBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) && // P2P GC + (prP2pBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) && // Connected + ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON) && // TX Beacon + EQUAL_SSID(prBssDesc->aucSSID, // SSID Match + prBssDesc->ucSSIDLen, + prP2pConnSettings->aucSSID, + prP2pConnSettings->ucSSIDLen)) { + + + prP2pBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod; + nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_P2P_INDEX); + } + + do { + RF_CHANNEL_INFO_T rChannelInfo; + + ASSERT_BREAK((prSwRfb != NULL) && (prBssDesc != NULL)); + + rChannelInfo.ucChannelNum = prBssDesc->ucChannelNum; + rChannelInfo.eBand = prBssDesc->eBand; + + 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); + + return; +} /* 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 + ) +{ + + return; +} /* 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: "MACSTR"\n", MAC2STR(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: "MACSTR"\n", MAC2STR(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: "MACSTR"\n", MAC2STR(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); + break; + } + + /* Final decision. */ + prCandidateBssDesc = prBssDesc; + break; + } + + + + } while (FALSE); + + return prCandidateBssDesc; +} /* scanP2pSearchDesc */ + + + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_state.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_state.c new file mode 100755 index 000000000000..cf108f3cb1a3 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/mgmt/p2p_state.c @@ -0,0 +1,544 @@ + +#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)); + DBGLOG(P2P, TRACE, ("p2pStateInit_IDLE \n")); + 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; + *peNextState = P2P_STATE_REQING_CHANNEL; + DBGLOG(P2P, TRACE, ("p2pStateInit_IDLE: peNextState = P2P_STATE_REQING_CHANNEL \n")); + + } + else { + prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; + + if (prChnlReqInfo->fgIsChannelRequested) { + /* Start a timer for return channel. */ + DBGLOG(P2P, TRACE, ("start a GO channel timer.\n")); + cnmTimerStartTimer(prAdapter, &(prP2pFsmInfo->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)); + DBGLOG(P2P, TRACE, ("p2pStateAbort_IDLE \n")); + prChnlReqInfo = &prP2pFsmInfo->rChnlReqInfo; + + if (prChnlReqInfo->fgIsChannelRequested) { + /* Stop timer for leaving this state. */ + cnmTimerStopTimer(prAdapter, &(prP2pFsmInfo->rP2pFsmTimeoutTimer)); + + /* Release channel before timeout. */ + p2pFuncReleaseCh(prAdapter, prChnlReqInfo); + DBGLOG(P2P, TRACE, ("p2pStateAbort_IDLE: Release channel \n")); + } + + + + } while (FALSE); + + return; +} /* p2pStateAbort_IDLE */ + + + +VOID +p2pStateInit_CHNL_ON_HAND ( + IN P_ADAPTER_T prAdapter, + 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); + + DBGLOG(P2P, TRACE, ("start a channel on hand timer.\n")); + cnmTimerStartTimer(prAdapter, + &(prP2pFsmInfo->rP2pFsmTimeoutTimer), + prChnlReqInfo->u4MaxInterval); + + kalP2PIndicateChannelReady(prAdapter->prGlueInfo, + prChnlReqInfo->u8Cookie, + prChnlReqInfo->ucReqChnlNum, + prChnlReqInfo->eBand, + prChnlReqInfo->eChnlSco, + prChnlReqInfo->u4MaxInterval); + + } while (FALSE); + + return; +} /* p2pStateInit_CHNL_ON_HAND */ + + +VOID +p2pStateAbort_CHNL_ON_HAND ( + IN P_ADAPTER_T prAdapter, + IN P_P2P_FSM_INFO_T prP2pFsmInfo, + IN ENUM_P2P_STATE_T eNextState + ) +{ + + cnmTimerStopTimer(prAdapter, &(prP2pFsmInfo->rP2pFsmTimeoutTimer)); + + if (eNextState != P2P_STATE_CHNL_ON_HAND) { + /* Indicate channel return. */ + kalP2PIndicateChannelExpired(prAdapter->prGlueInfo, &prP2pFsmInfo->rChnlReqInfo); + + // Return Channel. + p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); + } + + return; +} /* 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); + + return; +} /* 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); + + return; +} /* 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; + + if ((ucPreferedChnl = prP2pConnSettings->ucOperatingChnl) == 0) { + + if (scnQuerySparseChannel(prAdapter, &eBand, &ucPreferedChnl) == FALSE) { + + // What to do? + ASSERT(FALSE); + // TODO: Pick up a valid channel from channel list. + } + } + } + + + prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GO_START_BSS; + prChnlReqInfo->ucReqChnlNum = prP2pSpecificBssInfo->ucPreferredChannel = ucPreferedChnl; + prChnlReqInfo->eBand = prP2pSpecificBssInfo->eRfBand = eBand; + prChnlReqInfo->eChnlSco = prP2pSpecificBssInfo->eRfSco = eSco; + } + else { + p2pFuncCancelScan(prAdapter, &(prP2pFsmInfo->rScanReqInfo)); + } + + + } while (FALSE); + + return; +} /* 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)); + DBGLOG(P2P, TRACE, ("p2pStateInit_SCAN \n")); + prScanReqInfo = &prP2pFsmInfo->rScanReqInfo; + + prScanReqInfo->fgIsScanRequest = TRUE; + + p2pFuncRequestScan(prAdapter, prScanReqInfo); + + } while (FALSE); + return; +} /* 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); + + return; +} /* 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, + &(prP2pFsmInfo->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); + + return; +} /* 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, &(prP2pFsmInfo->rP2pFsmTimeoutTimer)); + + /* Release channel requested. */ + p2pFuncReleaseCh(prAdapter, &(prP2pFsmInfo->rChnlReqInfo)); + + } while (FALSE); + + return; + +} /* p2pStateAbort_GC_JOIN */ + + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/nic/p2p_nic.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/nic/p2p_nic.c new file mode 100755 index 000000000000..08240eb03e93 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/nic/p2p_nic.c @@ -0,0 +1,243 @@ +/* +** $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. +*/ + + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E 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 "p2p_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 (((UINT_32)prP2pInfo->pucCurrIePtr + (UINT_32)u2RxIELength) > + (UINT_32)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { + /* Common Buffer is no enough. */ + u2RxIELength = (UINT_16)((UINT_32)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - (UINT_32)prP2pInfo->pucCurrIePtr); + } + + /* Step to next buffer address. */ + prP2pInfo->pucCurrIePtr = (PUINT_8)((UINT_32)prP2pInfo->pucCurrIePtr + (UINT_32)u2RxIELength); + } + + /* Restore buffer pointer. */ + prTargetResult->pucIeBuf = pucIeBuf; + + if (pucRxIEBuf) { + /* If new received IE is availabe. + * 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 " MACSTR", " MACSTR "\n", prP2pInfo->u4DeviceNum, MAC2STR(prP2pResult->aucDeviceAddr), MAC2STR(prTargetResult->aucDeviceAddr)); + + if (u2RxIELength) { + prTargetResult->pucIeBuf = prP2pInfo->pucCurrIePtr; + + if (((UINT_32)prP2pInfo->pucCurrIePtr + (UINT_32)u2RxIELength) > + (UINT_32)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN]) { + /* Common Buffer is no enough. */ + u2IELength = (UINT_16)((UINT_32)&prP2pInfo->aucCommIePool[CFG_MAX_COMMON_IE_BUF_LEN] - (UINT_32)prP2pInfo->pucCurrIePtr); + } + else { + u2IELength = u2RxIELength; + } + + prP2pInfo->pucCurrIePtr = (PUINT_8)((UINT_32)prP2pInfo->pucCurrIePtr + (UINT_32)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/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p.c new file mode 100755 index 000000000000..beae128dcad4 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p.c @@ -0,0 +1,5405 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_p2p.c $ + * + * 03 26 2012 yuche.tsai + * [ALPS00255551] [WiFi direct][Google Issue]GC can't send picture to GO sometimes,GO and GC can't ping each other + * Avoid ran out of driver resource when starting GO. + * + * 02 24 2012 yuche.tsai + * [ALPS00240756] [WiFi direct]After accept PBC request,DVT pops Kernel Defect.Powering off DVT causes DVT reboots automatcially and pops up KE(once) + * Fix GO dissolving issue to avoid FW assert. + * + * 02 23 2012 chinglan.wang + * [ALPS00240621] [Wifi P2P]Run Sigma tool of A69. Always run fail on 7.1.3. sniffer check Sta-IsActive-No-Frames-With-PowerMgmt-1 + * . + * + * 02 21 2012 yuche.tsai + * [ALPS00239729] [Monkey][WiFi Direct][Driver] Avoid invalid function access after driver unload + * Refine error fix. + * + * 02 21 2012 yuche.tsai + * [ALPS00239729] [Monkey][WiFi Direct][Driver] Avoid invalid function access after driver unload + * Refine error fix of net device operation unregister. + * + * 02 21 2012 yuche.tsai + * [ALPS00239729] [Monkey][WiFi Direct][Driver] Avoid invalid function access after driver unload + * Avoid the net device operations been referenced by the kernel after device un-registered. + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 02 09 2012 yuche.tsai + * [ALPS00233022] [klocwork 9.1] in gl_p2p.c, line 4338 + * After code fix. + * + * 02 09 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Before code fix. + * + * 02 09 2012 yuche.tsai + * [ALPS00233021] [klocwork 9.1] in gl_p2p.c, line 1895 + * After code fix. + * + * 02 09 2012 yuche.tsai + * [ALPS00233021] [klocwork 9.1] in gl_p2p.c, line 1895 + * Before fix. + * + * 02 09 2012 yuche.tsai + * [ALPS00233019] [klocwork 9.1] in gl_p2p.c, line 1832 + * After code fix. + * + * 02 09 2012 yuche.tsai + * [ALPS00233019] [klocwork 9.1] in gl_p2p.c, line 1832 + * Before fixing warning code. + * + * 02 08 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Try to fix clockwork warning. + * + * 02 06 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Small bug fix for CNM memory usage, scan SSID search issue, P2P network deactivate issue. + * + * 01 31 2012 yuche.tsai + * NULL + * Fix compile error & del beacon scenario. + * + * 01 26 2012 yuche.tsai + * NULL + * Fix compile warning. + * + * 01 18 2012 yuche.tsai + * NULL + * Add get station info API. + * TX deauth before start beacon. + * + * 01 16 2012 chinglan.wang + * NULL + * Update security code.. + * + * 01 16 2012 yuche.tsai + * NULL + * Update security code. + * + * 01 15 2012 yuche.tsai + * NULL + * ICS P2P Driver Update. + * + * 01 15 2012 yuche.tsai + * NULL + * ICS Wi-Fi Direct Update. + * + * 01 13 2012 yuche.tsai + * NULL + * Update driver/p2p driver for ICS tethering mode. + * Fix FW reply probe request issue. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Tethering for ICS code update. - fix KE when indicate Probe Request. + * + * 01 13 2012 yuche.tsai + * NULL + * Update WiFi tethering driver for ICS. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 Channle 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 flag after Tx lifetime timeout of GO NEGO frame. + * + * 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 & WPS IE parsing. + * + * 04 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Rix retest 6.1.10 fail issue. + * + * 04 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Add device discoverability support. (Phase I) + * + * 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 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 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. Fix formation policy issue. + * 2. Fix LISTEN channel issue. + * 3. Fix Target IF address in-correct issue when being GO. + * + * 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 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 paramters + * + * 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include + +#include +//#include +#include "gl_p2p_ioctl.h" + +#include "p2p_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 +/* for cfg80211 - frequency table */ +/* default channel table for p2p network and WILL BE UPDATED based on device country code */ +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), +}; + +static struct ieee80211_channel mtk_5ghz_a_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), +}; + +/* 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 MT6620_MCS_INFO \ +{ \ + /* MCS1~7*/ \ + .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\ + .rx_highest = 0, \ + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ +} + +#if 0 +/*Bandwidth 20Mhz Only*/ +#define MT6620_HT_CAP \ +{ \ + .ht_supported = true, \ + .cap = IEEE80211_HT_CAP_SM_PS \ + | IEEE80211_HT_CAP_GRN_FLD \ + | IEEE80211_HT_CAP_SGI_20, \ + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \ + .mcs = MT6620_MCS_INFO, \ +} +#else +/*Bandwidth 20/40Mhz*/ +#define MT6620_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 = MT6620_MCS_INFO, \ +} +#endif + +static struct ieee80211_supported_band mtk_band_2ghz = { + .band = IEEE80211_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 = MT6620_HT_CAP, +}; + +static struct ieee80211_supported_band mtk_band_5ghz = { + .band = IEEE80211_BAND_5GHZ, + .channels = mtk_5ghz_a_channels, + .n_channels = ARRAY_SIZE(mtk_5ghz_a_channels), + .bitrates = mtk_a_rates, + .n_bitrates = mtk_a_rates_size, + .ht_cap = MT6620_HT_CAP, +}; + +static const UINT_32 cipher_suites[] = { + /* 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 +}; + +static struct cfg80211_ops mtk_p2p_config_ops = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) + /* Froyo */ + .change_virtual_intf = mtk_p2p_cfg80211_change_iface, // 1 st + .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, + .add_beacon = mtk_p2p_cfg80211_add_set_beacon, + .set_beacon = mtk_p2p_cfg80211_add_set_beacon, + .del_beacon = mtk_p2p_cfg80211_del_beacon, + .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params, + .del_station = mtk_p2p_cfg80211_del_station, + .set_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 +#endif +}; + + + +/* 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 +}; + +/******************************************************************************* +* M A 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) +{ + skb->priority = _p2p_cfg80211_classify8021d(skb); + + return au16Wlan1dToQueueIdx[skb->priority]; +} + +static struct net_device *g_P2pPrDev; + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 + ) +{ + if (!prDev) { + return -ENXIO; + } + + 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 + ) +{ + + + return; +} /* end of p2pUninit() */ + + + + + + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) +static const struct net_device_ops p2p_netdev_ops = { + .ndo_open = p2pOpen, + .ndo_stop = p2pStop, + .ndo_set_mac_address = p2pSetMACAddress, + .ndo_set_multicast_list = p2pSetMulticastList, + .ndo_get_stats = p2pGetStats, + .ndo_do_ioctl = p2pDoIOCTL, + .ndo_start_xmit = p2pHardStartXmit, + .ndo_select_queue = p2pSelectQueue, + .ndo_init = p2pInit, + .ndo_uninit = p2pUninit, +}; + +static const struct net_device_ops p2p_null_ops = { + .ndo_open = NULL, + .ndo_stop = NULL, + .ndo_set_mac_address = NULL, + .ndo_set_multicast_list = NULL, + .ndo_get_stats = NULL, + .ndo_do_ioctl = NULL, + .ndo_start_xmit = NULL, + .ndo_select_queue = NULL, + .ndo_init = NULL, + .ndo_uninit = NULL, +}; + +#endif + + +/******************************************************************************* +* 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( + P_GLUE_INFO_T prGlueInfo + ) +{ + P_ADAPTER_T prAdapter = NULL; + P_WIFI_VAR_T prWifiVar = NULL; + + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + prWifiVar = &(prAdapter->rWifiVar); + + ASSERT(prAdapter); + ASSERT(prWifiVar); + + /*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); + + /*MUST set memory to 0 */ + kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T)); + kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T)); + kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T)); + kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T)); + kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T)); + + /* chk if alloc successful or not*/ + if (prGlueInfo->prP2PInfo && + prGlueInfo->prAdapter->prP2pInfo && + prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings && + prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo && + prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo) + { + return TRUE; + } + else { + 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 + ) +{ + + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prAdapter); + + /* 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; + } + +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Enable Channel for cfg80211 for Wi-Fi Direct based on current country code +* +* \param[in] prGlueInfo Pointer to glue info +* +* \return TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +VOID +p2pEnableChannel( + PUINT_8 pucChIdx, + UINT_8 ucChannelNum, + struct ieee80211_channel *mtk_channels, + UINT_8 mtk_channel_sz +) +{ + UINT_8 ucCurChIdx = *pucChIdx; + + while(TRUE) { + (*pucChIdx)++; + (*pucChIdx) %= mtk_channel_sz; + + if(ucChannelNum == mtk_channels[*pucChIdx].hw_value) { + mtk_channels[*pucChIdx].flags &= ~IEEE80211_CHAN_DISABLED; + break; + } + + if(*pucChIdx == ucCurChIdx) { + printk(KERN_ALERT DRV_NAME "Orphan channel [%d]\n", ucChannelNum); + break; + } + } +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current country code +* +* \param[in] prGlueInfo Pointer to glue info +* +* \return TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +VOID +p2pUpdateChannelTableByDomain( + P_GLUE_INFO_T prGlueInfo + ) +{ + UINT_8 i, uc2gChIdx, uc5gChIdx; + UINT_8 ucMaxChannelNum = ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_a_channels); + UINT_8 ucNumOfChannel = ucMaxChannelNum; + RF_CHANNEL_INFO_T aucChannelList[ucMaxChannelNum]; + + uc2gChIdx = uc5gChIdx = 0; + + // 1. Disable all channel + for(i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) { + mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED; + } + for(i = 0; i < ARRAY_SIZE(mtk_5ghz_a_channels); i++) { + mtk_5ghz_a_channels[i].flags |= IEEE80211_CHAN_DISABLED; + } + + // 2. Get current domain channel list + rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_NULL, ucMaxChannelNum, &ucNumOfChannel, aucChannelList); + + // 3. Enable specific channel based on domain channel list + for(i = 0; i < ucNumOfChannel; i++) { + switch(aucChannelList[i].eBand) { + case BAND_2G4: + p2pEnableChannel(&uc2gChIdx, aucChannelList[i].ucChannelNum, mtk_2ghz_channels, ARRAY_SIZE(mtk_2ghz_channels)); + break; + + case BAND_5G: + p2pEnableChannel(&uc5gChIdx, aucChannelList[i].ucChannelNum, mtk_5ghz_a_channels, ARRAY_SIZE(mtk_5ghz_a_channels)); + break; + + default: + printk(KERN_ALERT DRV_NAME "Unknow band.\n"); + break; + + } + } + +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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; +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + struct device *prDev; +#endif + + ASSERT(prGlueInfo); + + prAdapter = prGlueInfo->prAdapter; + ASSERT(prAdapter); + + prHif = &prGlueInfo->rHifInfo; + ASSERT(prHif); + + /*0. allocate p2pinfo */ + if(!p2PAllocInfo(prGlueInfo)) { + printk(KERN_ALERT DRV_NAME "Allocate memory for p2p FAILED\n"); + ASSERT(0); + return FALSE; + } +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + /* 1. allocate WIPHY */ + prGlueInfo->prP2PInfo->wdev.wiphy = wiphy_new(&mtk_p2p_config_ops, sizeof(P_GLUE_INFO_T)); + if (!prGlueInfo->prP2PInfo->wdev.wiphy) { + printk(KERN_ALERT DRV_NAME "unable to allocate wiphy for p2p\n"); + + goto err_alloc_wiphy; + } + + /* 1.1 fill wiphy parameters */ +#if MTK_WCN_HIF_SDIO + mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev); + if(!prDev) { + printk(KERN_ALERT DRV_NAME "unable to get struct dev for p2p\n"); + } +#else + prDev = &(prHif->func->dev); +#endif + set_wiphy_dev(prGlueInfo->prP2PInfo->wdev.wiphy, prDev); + + prGlueInfo->prP2PInfo->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) + | BIT(NL80211_IFTYPE_P2P_CLIENT) + | BIT(NL80211_IFTYPE_P2P_GO) + | BIT(NL80211_IFTYPE_STATION); + + p2pUpdateChannelTableByDomain(prGlueInfo); + prGlueInfo->prP2PInfo->wdev.wiphy->bands[IEEE80211_BAND_2GHZ] = &mtk_band_2ghz; + if(prAdapter->fgEnable5GBand) { + prGlueInfo->prP2PInfo->wdev.wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz; + } + + prGlueInfo->prP2PInfo->wdev.wiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes; + prGlueInfo->prP2PInfo->wdev.wiphy->max_remain_on_channel_duration = 5000; + prGlueInfo->prP2PInfo->wdev.wiphy->n_cipher_suites = 5; + prGlueInfo->prP2PInfo->wdev.wiphy->cipher_suites = (const u32*)cipher_suites; + prGlueInfo->prP2PInfo->wdev.wiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) + prGlueInfo->prP2PInfo->wdev.wiphy->max_scan_ssids = MAX_SCAN_LIST_NUM; + prGlueInfo->prP2PInfo->wdev.wiphy->max_scan_ie_len = MAX_SCAN_IE_LEN; + prGlueInfo->prP2PInfo->wdev.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; +#endif + + /* 2. Register WIPHY */ + if(wiphy_register(prGlueInfo->prP2PInfo->wdev.wiphy) < 0) { + printk(KERN_ALERT DRV_NAME "Couldn't register wiphy device for p2p\n"); + + goto err_reg_wiphy; + } + + /* 2.1 set priv as pointer to glue structure */ + *((P_GLUE_INFO_T *) wiphy_priv(prGlueInfo->prP2PInfo->wdev.wiphy)) = prGlueInfo; + + /* 2.2 wdev initialization */ + if(fgIsApMode) { + prGlueInfo->prP2PInfo->wdev.iftype = NL80211_IFTYPE_AP; + } else { + prGlueInfo->prP2PInfo->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; + } + +#endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */ + + /* 3. allocate netdev */ + prGlueInfo->prP2PInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, ether_setup, CFG_MAX_TXQ_NUM); + if (!prGlueInfo->prP2PInfo->prDevHandler) { + printk(KERN_ALERT DRV_NAME "unable to allocate netdevice for p2p\n"); + + goto err_alloc_netdev; + } + + /* 4. setup netdev */ + /* 4.1 Point to shared glue structure */ + *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = 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 */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) + prGlueInfo->prP2PInfo->prDevHandler->netdev_ops = &p2p_netdev_ops; +#else + prGlueInfo->prP2PInfo->prDevHandler->open = p2pOpen; + prGlueInfo->prP2PInfo->prDevHandler->stop = p2pStop; + prGlueInfo->prP2PInfo->prDevHandler->get_stats = p2pGetStats; + prGlueInfo->prP2PInfo->prDevHandler->set_multicast_list = p2pSetMulticastList; + prGlueInfo->prP2PInfo->prDevHandler->hard_start_xmit = p2pHardStartXmit; + prGlueInfo->prP2PInfo->prDevHandler->do_ioctl = p2pDoIOCTL; + prGlueInfo->prP2PInfo->prDevHandler->set_mac_address = p2pSetMACAddress; +#endif +// prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers = &mtk_p2p_wext_handler_def; + +#if (MTK_WCN_HIF_SDIO == 0) + SET_NETDEV_DEV(prGlueInfo->prP2PInfo->prDevHandler, &(prHif->func->dev)); +#endif + + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + prGlueInfo->prP2PInfo->prDevHandler->ieee80211_ptr = &(prGlueInfo->prP2PInfo->wdev); + prGlueInfo->prP2PInfo->wdev.netdev = prGlueInfo->prP2PInfo->prDevHandler; +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + prGlueInfo->prP2PInfo->prDevHandler->features = NETIF_F_IP_CSUM; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + /* 7. net device initialize */ + netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); + netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); + + /* 8. register for net device */ + if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) { + printk(KERN_ALERT DRV_NAME "unable to register netdevice for p2p\n"); + + goto err_reg_netdev; + } + + /* 9. setup running mode*/ + prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode; + + /* 10. finish */ + p2pFsmInit(prAdapter); + + p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings); + + nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX); + + return TRUE; + +err_reg_netdev: + free_netdev(prGlueInfo->prP2PInfo->prDevHandler); + +err_alloc_netdev: +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + wiphy_unregister(prGlueInfo->prP2PInfo->wdev.wiphy); + +err_reg_wiphy: + wiphy_free(prGlueInfo->prP2PInfo->wdev.wiphy); + prGlueInfo->prP2PInfo->wdev.wiphy = NULL; + +err_alloc_wiphy: +#endif + + return FALSE; +} /* 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); + + p2pFsmUninit(prGlueInfo->prAdapter); + + nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); + +#if 0 + /* Release command, mgmt and security frame belong to P2P network in + * prGlueInfo->prCmdQue + * prAdapter->rPendingCmdQueue + * prAdapter->rTxCtrl.rTxMgmtTxingQueue + * To ensure there is no pending CmdDone/TxDone handler to be executed after p2p module is removed. + */ + + /* Clear CmdQue*/ + kalClearMgmtFramesByNetType(prGlueInfo, NETWORK_TYPE_P2P_INDEX); + kalClearSecurityFramesByNetType(prGlueInfo, NETWORK_TYPE_P2P_INDEX); + /* Clear PendingCmdQue*/ + wlanReleasePendingCMDbyNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); + /* Clear PendingTxMsdu */ + nicFreePendingTxMsduInfoByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX); +#endif + + /* prepare for removal */ + if(netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) { + netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler); + } + + netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler); + + /* netdevice unregistration & free */ + unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler); + +#if 1 // 20120221 frog: Avoid been referenced by netlink after net device unregistered. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) + prGlueInfo->prP2PInfo->prDevHandler->netdev_ops = &p2p_null_ops; +#endif +#endif + + free_netdev(prGlueInfo->prP2PInfo->prDevHandler); + prGlueInfo->prP2PInfo->prDevHandler = NULL; + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + wiphy_unregister(prGlueInfo->prP2PInfo->wdev.wiphy); + wiphy_free(prGlueInfo->prP2PInfo->wdev.wiphy); + prGlueInfo->prP2PInfo->wdev.wiphy = NULL; +#endif + + /* Free p2p memory */ + if(!p2PFreeInfo(prGlueInfo)) { + printk(KERN_ALERT DRV_NAME "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 + printk(KERN_ALERT DRV_NAME "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; + + 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); +#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 + 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)); + + //@FIXME + 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; +} /* 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) { + printk(KERN_WARNING DRV_NAME" 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; + /* wake up main thread */ + wake_up_interruptible(&prGlueInfo->waitq); + +} /* p2pSetMulticastList */ + + +/*----------------------------------------------------------------------------*/ +/*! + * \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) { + printk(KERN_WARNING DRV_NAME" 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) || +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { +#else + (prDev->mc_count > MAX_NUM_GROUP_ADDR)) { +#endif + 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 */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + struct netdev_hw_addr *ha; +#else + struct dev_mc_list *prMcList; +#endif + UINT_32 i = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + netdev_for_each_mc_addr(ha, prDev) { + if(i < MAX_NUM_GROUP_ADDR) { + COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr); + i++; + } + } +#else + for (i = 0, prMcList = prDev->mc_list; + (prMcList) && (i < prDev->mc_count) && (i < MAX_NUM_GROUP_ADDR); + i++, prMcList = prMcList->next) { + COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), prMcList->dmi_addr); + } +#endif + + 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); + + } + + return; +} /* end of p2pSetMulticastList() */ + + +/*----------------------------------------------------------------------------*/ +/*! + * * \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)); + + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip tx\n"); + dev_kfree_skb(prSkb); + return NETDEV_TX_OK; + } + + // mark as P2P packets + GLUE_SET_PKT_FLAG_P2P(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) { + printk(KERN_INFO DRV_NAME"Incorrect queue index, skip this frame\n"); + 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) { + netif_stop_subqueue(prDev, u2QueueIdx); + } + } + else { + GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); + } + + kalSetEvent(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 WLAN_STATUS_SUCCESS The IOCTL command is executed successfully. + * \retval OTHER 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); + + prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); + + if (prGlueInfo->u4ReadyFlag == 0) { + // adapter not ready yet + return -EINVAL; + } + + // fill rIwReqInfo + 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)) { + printk(KERN_INFO "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 + default: + ret = -ENOTTY; + } + + return ret; +} /* end of p2pDoIOCTL() */ + + +/*----------------------------------------------------------------------------*/ +/*! + * \brief To report the private supported IOCTLs table to user space. + * + * \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 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 = 0; + + ASSERT(prDev); + + u2BufferSize = prData->length; + + /* update our private table size */ + prData->length = (__u16)sizeof(rP2PIwPrivTable)/sizeof(struct iw_priv_args); + + 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); + + // indicate P2P-FSM with MID_MNY_P2P_CONNECTION_TRIGGER + 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 */ + prMsgHdr->eMsgId = MID_MNY_P2P_CONNECTION_TRIGGER; + + 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: + // indicate P2P-FSM with MID_MNY_P2P_CONNECTION_PAUSE + 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 */ + prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_PAUSE; + } + + /* 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: + /* indicate P2P-FSM with MID_MNY_P2P_PROVISION_COMPLETE */ + 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 */ + prMsgHdr->eMsgId = MID_MNY_P2P_PROVISION_COMPLETE; + + 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: + /* @TODO: send to P2P-FSM with MID_MNY_P2P_PROVISION_COMPLETE, with fail code */ + + 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) { + // indicate P2P-FSM with MID_MNY_P2P_DISCOVERY_ABORT + 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; + } + + prMsgHdr->eMsgId = MID_MNY_P2P_DISCOVERY_ABORT; + + 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 */ + prMsgP2PInvitationReq->rMsgHdr.eMsgId = MID_MNY_P2P_INVITATION_REQ; + 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; + } + else { + 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 */ + prMsgP2PInvitationAbort->rMsgHdr.eMsgId = MID_MNY_P2P_INVITATION_ABORT; + 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; + prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE); + + if (!prExtraBuf) { + ret = -ENOMEM; + break; + } + + 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; + prIWEncExt = (struct iw_encode_ext *) prExtraBuf; + + if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) == TRUE) { + 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 = ((UINT_32)&(((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; + } + } + } + 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 { + printk(KERN_DEBUG "%s(): unsupported power management mode value = %d.\n", + __FUNCTION__, + 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; + + 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 = 8 + sizeof("p2p_cap="); + + 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 = 12 + sizeof("p2p_dev_type="); + + 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="); + + snprintf(data, iwe.u.data.length, "p2p_grp_bssid="MACSTR"%c", + MAC2STR(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]; + + printk("set parameter, u4SubCmd=%d idx=%d value=%lu\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)) { + printk(KERN_INFO DRV_NAME"extra buffer is valid\n"); + } + else { + printk(KERN_INFO DRV_NAME"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)) { +// 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)) { +// 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)) { + printk(KERN_INFO DRV_NAME"extra buffer is valid\n"); + } + else { + printk(KERN_INFO DRV_NAME"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)) { + printk(KERN_INFO DRV_NAME"extra buffer is valid\n"); + } + else { + printk(KERN_INFO DRV_NAME"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) { + printk(KERN_INFO DRV_NAME "%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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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; + + for (i=0; iaucBuffer[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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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))) { + printk(KERN_NOTICE "%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; + 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; + } + else { + prP2PReq->outBufferLength = u4QueryInfoLen; + + if(copy_to_user(wrqu->data.pointer, + &(prGlueInfo->prP2PInfo->aucOidBuf[0]), + u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { + printk(KERN_NOTICE "%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; + 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; + } + else { + prP2PReq->outBufferLength = u4QueryInfoLen; + + if(copy_to_user(wrqu->data.pointer, + &(prGlueInfo->prP2PInfo->aucOidBuf[0]), + u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { + printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__); + return -EIO; + } + else { + 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; + 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); + + printk("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; + } + else { + prP2PReq->outBufferLength = u4QueryInfoLen; + + if(copy_to_user(wrqu->data.pointer, + prP2PReq->aucBuffer, + u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) { + printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__); + return -EIO; + } + else { + 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_STRUC_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUC_T)extra; + P_GLUE_INFO_T prGlueInfo = NULL; + + ASSERT(prDev); + + prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); + ASSERT(prGlueInfo); + + printk("mtk_p2p_wext_set_noa_param\n"); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetNoaParam, + prNoaParam, //prP2PReq->aucBuffer, + sizeof(PARAM_CUSTOM_NOA_PARAM_STRUC_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_STRUC_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUC_T)extra; + P_GLUE_INFO_T prGlueInfo = NULL; + + ASSERT(prDev); + + prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); + ASSERT(prGlueInfo); + + printk("mtk_p2p_wext_set_oppps_param\n"); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetOppPsParam, + prOppPsParam, //prP2PReq->aucBuffer, + sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUC_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/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_cfg80211.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_cfg80211.c new file mode 100755 index 000000000000..868aeb032555 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_cfg80211.c @@ -0,0 +1,1755 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_p2p_cfg80211.c $ + * + * 02 23 2012 chinglan.wang + * [ALPS00240621] [Wifi P2P]Run Sigma tool of A69. Always run fail on 7.1.3. sniffer check Sta-IsActive-No-Frames-With-PowerMgmt-1 + * . + * + * 02 06 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Small bug fix for CNM memory usage, scan SSID search issue, P2P network deactivate issue. + * + * 01 31 2012 yuche.tsai + * NULL + * Fix compile error & del beacon scenario. + * + * 01 27 2012 yuche.tsai + * NULL + * Update for GC connection . + * + * 01 26 2012 yuche.tsai + * NULL + * Fix compile warning. + * + * 01 18 2012 yuche.tsai + * NULL + * Bug fix for memory allocation. + * + * 01 18 2012 yuche.tsai + * NULL + * Change debug log from printk to DBGLOG. + * Fix probe request issue. + * + * 01 18 2012 yuche.tsai + * NULL + * Add get station info API. + * TX deauth before start beacon. + * + * 01 17 2012 wh.su + * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting + * adding the code to fix the add key function. + * + * 01 17 2012 yuche.tsai + * NULL + * Update mgmt frame filter setting. + * Please also update FW 2.1 + * + * 01 16 2012 yuche.tsai + * NULL + * Update Driver for wifi driect gc join IE update issue. + * + * 01 16 2012 chinglan.wang + * NULL + * Update security code.. + * + * 01 16 2012 yuche.tsai + * NULL + * Fix wifi direct scan bug. + * + * 01 15 2012 yuche.tsai + * NULL + * Update P2P scan issue for ICS. + * + * 01 15 2012 yuche.tsai + * NULL + * ICS P2P Driver Update. + * + * 01 15 2012 yuche.tsai + * NULL + * Fix p2p scan bug. + * + * 01 15 2012 yuche.tsai + * NULL + * Fix scan bug. + * + * 01 15 2012 yuche.tsai + * NULL + * ICS Wi-Fi Direct Update. + * + * 01 13 2012 yuche.tsai + * NULL + * Update driver/p2p driver for ICS tethering mode. + * Fix FW reply probe request issue. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Tethering for ICS code update. - fix KE when indicate Probe Request. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Direct Driver Update for ICS. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 01 09 2012 terry.wu + * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork + * cfg80211 integration for p2p network. + * + * 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. + * + * 09 21 2010 kevin.huang + * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface + * Isolate P2P related function for Hardware Software Bundle + * + * 07 08 2010 cp.wu + * + * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. + * + * 06 06 2010 kevin.huang + * [WPD00003832][MT6620 5931] Create driver base + * [MT6620 5931] Create driver base + * + * 05 31 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * add cfg80211 interface, which is to replace WE, for further extension + * +** +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ + +#include "config.h" + +#if CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 +#include +#include +#include +#include +#include + +#include "p2p_precomp.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +#if 0 +static add_set_beacon_count = 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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 +******************************************************************************** +*/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) +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) { + memcpy(rKey.arBSSID, mac_addr, ETH_ALEN); + if (rKey.arBSSID[1] == 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.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); //???? + } + 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 = ((UINT_32)&(((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)); + + 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 -EINVAL; +} + +int mtk_p2p_cfg80211_get_station( + struct wiphy *wiphy, + struct net_device *ndev, + 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, + mac, + &rP2pStaInfo); + + /* Inactive time. */ + sinfo->filled |= STATION_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 net_device *ndev, + 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---------] */ + + + 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; + break; + } + + + DBGLOG(P2P, TRACE, ("Generating scan request message.\n")); + + prMsgScanRequest->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY; + + + + DBGLOG(P2P, TRACE, ("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 IEEE80211_BAND_2GHZ: + prRfChannelInfo->eBand = BAND_2G4; + break; + case IEEE80211_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 (request->n_ssids) { + ASSERT(prSsidStruct == &(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++; + } + + + DBGLOG(P2P, TRACE, ("Finish SSID list.\n")); + + /* 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")); + + + 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, + 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, + 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; + + ASSERT(wiphy); + + prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); + + // not implemented yet + + return -EINVAL; +} + +//&&&&&&&&&&&&&&&&&&&&&&&&&& Add for ICS Wi-Fi Direct Support. &&&&&&&&&&&&&&&&&&&&&&& + +int +mtk_p2p_cfg80211_add_set_beacon ( + struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *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; + } + #if 0 + if (add_set_beacon_count >= 1) { + break; + } + #endif + + + + DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_add_set_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; + } + + #if 0 + add_set_beacon_count += 1; + #endif + 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)((UINT_32)pucBuffer + (UINT_32)info->head_len); + } + else { + prP2pBcnUpdateMsg->u4BcnHdrLen = 0; + + prP2pBcnUpdateMsg->pucBcnHdr = NULL; + } + + if (info->tail_len != 0) { + UINT_8 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; + } + + prP2pBcnUpdateMsg->u4BcnInterval = info->interval; + + prP2pBcnUpdateMsg->u4DtimPeriod = info->dtim_period; + + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (P_MSG_HDR_T)prP2pBcnUpdateMsg, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + + } while (FALSE); + + return i4Rslt; +} + + +int +mtk_p2p_cfg80211_del_beacon ( + 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_del_beacon.\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_BEACON_DEL; + + mboxSendMsg(prGlueInfo->prAdapter, + MBOX_ID_0, + (P_MSG_HDR_T)prP2pSwitchMode, + MSG_SEND_METHOD_BUF); + + i4Rslt = 0; + } while (FALSE); + + + return i4Rslt; +} /* mtk_p2p_cfg80211_del_beacon */ + +// TODO: +int +mtk_p2p_cfg80211_deauth ( + struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_deauth_request *req, + void *cookie + ) +{ + + 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, + void *cookie + ) +{ + 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 net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + 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) || + (dev == 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, + channel_type, + &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 net_device *dev, + 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) || (dev == 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 net_device *dev, + struct ieee80211_channel *chan, bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, unsigned int wait, + const u8 *buf, + size_t len, + 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; + 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) || + (buf == NULL) || + (len == 0) || + (dev == NULL) || + (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; + } + + + prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32)(len + MAC_TX_RESERVED_FIELD)); + + if ((prMsgTxReq->prMgmtMsduInfo = prMgmtFrame) == NULL) { + ASSERT(FALSE); + i4Rslt = -ENOMEM; + break; + } + + + prMsgTxReq->u8Cookie = *cookie; + prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_TX; + + pucFrameBuf = (PUINT_8)((UINT_32)prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD); + + kalMemCopy(pucFrameBuf, buf, len); + + prMgmtFrame->u2FrameLength = 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, + 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; + + + do { + if ((wiphy == NULL) || + (dev == NULL) || + (mac == NULL)) { + break; + } + + + 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); + + 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; +} + +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, TRACE, ("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; + break; + } + + + prDisconnMsg->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT; + prDisconnMsg->u2ReasonCode = reason_code; + 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; +} + + +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, + IN struct net_device *dev, + IN struct ieee80211_channel *chan, + IN enum nl80211_channel_type channel_type) +{ + INT_32 i4Rslt = -EINVAL; + P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL; + RF_CHANNEL_INFO_T rRfChnlInfo; + + do { + if ((wiphy == NULL) || + (dev == NULL) || + (chan == 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(chan, + channel_type, + &rRfChnlInfo, + NULL); + + p2pFuncSetChannel(prGlueInfo->prAdapter, &rRfChnlInfo); + + i4Rslt = 0; + } +while (FALSE); + + return i4Rslt; + +} + +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, + IN struct net_device *dev, + IN u16 frame_type, + IN bool reg + ) +{ + P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T)NULL; + P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL; + + do { + if ((wiphy == NULL) || + (dev == NULL)) { + break; + } + + + DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_mgmt_frame_register\n")); + + prGlueInfo = *((P_GLUE_INFO_T *) wiphy_priv(wiphy)); + + prMgmtFrameRegister = 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); + + } while (FALSE); + + + return; +} /* 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 IEEE80211_BAND_2GHZ: + prRfChnlInfo->eBand = BAND_2G4; + break; + case IEEE80211_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 void *data, + IN int len + ) +{ + P_GLUE_INFO_T prGlueInfo = NULL; + NL80211_DRIVER_TEST_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_PARAMS)); + + prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo; + prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings; + + DBGLOG(P2P, TRACE, ("mtk_p2p_cfg80211_testmode_cmd\n")); + + if(data && len) + memcpy(&rParams, data, len); + + DBGLOG(P2P, TRACE, ("NL80211_ATTR_TESTDATA,idx_mode=%d idx=%d value=%lu\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; + 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; + +} +#endif + + +#endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) + +#endif // CFG_ENABLE_WIFI_DIRECT && CFG_ENABLE_WIFI_DIRECT_CFG_80211 diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_init.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_init.c new file mode 100755 index 000000000000..6a6152ce6172 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_init.c @@ -0,0 +1,709 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2011 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/******************************************************************************* +* C O M P I L E 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 "p2p_precomp.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#define P2P_MODE_INF_NAME "p2p%d"; +#define AP_MODE_INF_NAME "ap%d"; +//#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 +******************************************************************************** +*/ + +MODULE_AUTHOR(NIC_AUTHOR); +MODULE_DESCRIPTION(NIC_DESC); +MODULE_SUPPORTED_DEVICE(NIC_NAME); + +#if MTK_WCN_HIF_SDIO + MODULE_LICENSE("MTK Propietary"); +#else + MODULE_LICENSE("GPL"); +#endif + +/******************************************************************************* +* 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; + +//module_param(ifname, charp, 0000); +//MODULE_PARM_DESC(ifname, "P2P Interface Name"); + +module_param(mode, ushort, 0000); +MODULE_PARM_DESC(mode, "Running 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 +******************************************************************************** +*/ + +extern int glRegisterEarlySuspend( + struct early_suspend *prDesc, + early_suspend_callback wlanSuspend, + late_resume_callback wlanResume); + +extern int glUnregisterEarlySuspend(struct early_suspend *prDesc); + +/******************************************************************************* +* 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 +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* register p2p pointer to wlan module +* +* +* \retval 1 Success +*/ +/*----------------------------------------------------------------------------*/ +BOOLEAN +p2pRegisterToWlan( + P_GLUE_INFO_T prGlueInfo + ) +{ + P_P2P_FUNCTION_LINKER prFuncLkr = (P_P2P_FUNCTION_LINKER)NULL; + extern APPEND_VAR_IE_ENTRY_T txProbRspIETableWIP2P[]; + extern P_APPEND_VAR_IE_ENTRY_T prTxProbRspIETableWIP2P; + extern MSG_HNDL_ENTRY_T arMsgMapTable[]; + + printk(KERN_INFO DRV_NAME "P2P register to wlan\n"); + + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prAdapter); + + if(prGlueInfo) { + + prFuncLkr = &(prGlueInfo->prAdapter->rP2pFuncLkr); + + /*set p2p function pointer to its function*/ + prFuncLkr->prKalP2pGetCipher = kalP2PGetCipher; // TODO: Leave to Maggie. + prFuncLkr->prKalP2pGetTkipCipher = kalP2PGetTkipCipher; // TODO: Leave to Maggie. + prFuncLkr->prKalP2pGetCcmpCipher = kalP2PGetCcmpCipher; // TODO: Leave to Maggie. + prFuncLkr->prKalP2pGetWscMode = kalP2PGetWscMode; // TODO: Leave to Maggie. + prFuncLkr->prKalP2pGetDevHdlr = kalP2PGetDevHdlr; + prFuncLkr->prKalP2pUpdateAssocInfo = kalP2PUpdateAssocInfo; + prFuncLkr->prP2pValidateAuth = p2pFuncValidateAuth; + prFuncLkr->prP2pValidateAssocReq = p2pFuncValidateAssocReq; + + prFuncLkr->prP2pRunEventAAATxFail = p2pRunEventAAATxFail; + prFuncLkr->prP2pRunEventAAAComplete = p2pRunEventAAAComplete; + prFuncLkr->prP2pRunEventAAASuccess = p2pRunEventAAASuccess; + prFuncLkr->prP2pParseCheckForP2pInfoElem = p2pFuncParseCheckForP2PInfoElem; + prFuncLkr->prP2pProcessEvent_UpdateNOAParam = p2pProcessEvent_UpdateNOAParam; // TODO: Leave to George. + prFuncLkr->prScanP2pProcessBeaconAndProbeResp = scanP2pProcessBeaconAndProbeResp; + prFuncLkr->prP2pRxPublicActionFrame = p2pFuncValidateRxActionFrame; + prFuncLkr->prP2pRxActionFrame = p2pFuncValidateRxActionFrame; + prFuncLkr->prRlmRspGenerateObssScanIE = rlmRspGenerateObssScanIE; // TODO: Leave to CM. + prFuncLkr->prRlmProcessPublicAction = rlmProcessPublicAction; // TODO: Leave to CM. + prFuncLkr->prRlmProcessHtAction = rlmProcessHtAction; // TODO: Leave to CM. + prFuncLkr->prRlmHandleObssStatusEventPkt = rlmHandleObssStatusEventPkt; // TODO: Leave to CM. + + prFuncLkr->prP2pCalculateP2p_IELenForBeacon = p2pFuncCalculateP2p_IELenForBeacon; + prFuncLkr->prP2pGenerateP2p_IEForBeacon = p2pFuncGenerateP2p_IEForBeacon; + + prFuncLkr->prP2pCalculateWSC_IELenForBeacon = p2pFuncCalculateWSC_IELenForBeacon; + prFuncLkr->prP2pGenerateWSC_IEForBeacon = p2pFuncGenerateWSC_IEForBeacon; + + prFuncLkr->prP2pCalculateP2p_IELenForAssocRsp = p2pFuncCalculateP2p_IELenForAssocRsp; + prFuncLkr->prP2pGenerateP2p_IEForAssocRsp = p2pFuncGenerateP2p_IEForAssocRsp; + + prFuncLkr->prP2pFuncValidateProbeReq = p2pFuncValidateProbeReq; + prFuncLkr->prRlmBssInitForAP = rlmBssInitForAP; // TODO: Leave to CM. + prFuncLkr->prP2pGetTxProbRspIETAbleSize = p2pGetTxProbRspIeTableSize; // TODO: It should not be called. + prFuncLkr->prRlmUpdateParamsForAp = rlmUpdateParamsForAP; // TODO: Leave to CM. + prFuncLkr->prP2pBuildReassocReqFrameCommIEs = p2pBuildReAssocReqFrameCommonIEs; + prFuncLkr->prP2pFuncDisconnect = p2pFuncDisconnect; + prFuncLkr->prP2pFsmRunEventRxDeauthentication = p2pFsmRunEventRxDeauthentication; + prFuncLkr->prP2pFsmRunEventRxDisassociation = p2pFsmRunEventRxDisassociation; + prFuncLkr->prP2pFuncIsApMode = p2pFuncIsAPMode; + prFuncLkr->prP2pFsmRunEventBeaconTimeout = p2pFsmRunEventBeaconTimeout; + prFuncLkr->prP2pSetMulticastListWorkQueue = mtk_p2p_wext_set_Multicastlist; + prFuncLkr->prP2pFuncStoreAssocRspIeBuffer = p2pFuncStoreAssocRspIEBuffer; + prFuncLkr->prP2pCalculate_IELenForAssocReq = p2pCalculate_IEForAssocReq; + prFuncLkr->prP2pGenerate_IEForAssocReq = p2pGenerate_IEForAssocReq; + /*set this pointer to the FIRST entry of rsp IE table*/ + prTxProbRspIETableWIP2P = &(txProbRspIETableWIP2P[0]); + + /*replace arMsgMapTable mboxDummy to real p2p handler*/ + arMsgMapTable[MID_P2P_SAA_FSM_START].pfMsgHndl = saaFsmRunEventStart; + arMsgMapTable[MID_P2P_SAA_FSM_ABORT].pfMsgHndl = saaFsmRunEventAbort; + arMsgMapTable[MID_CNM_P2P_CH_GRANT].pfMsgHndl = p2pFsmRunEventChGrant; + arMsgMapTable[MID_SCN_P2P_SCAN_DONE].pfMsgHndl = p2pFsmRunEventScanDone; + arMsgMapTable[MID_SAA_P2P_JOIN_COMPLETE].pfMsgHndl = p2pFsmRunEventJoinComplete; + arMsgMapTable[MID_MNY_P2P_FUN_SWITCH].pfMsgHndl = p2pFsmRunEventSwitchOPMode; + arMsgMapTable[MID_MNY_P2P_DEVICE_DISCOVERY].pfMsgHndl = p2pFsmRunEventScanRequest; + arMsgMapTable[MID_MNY_P2P_CONNECTION_REQ].pfMsgHndl = p2pFsmRunEventConnectionRequest; + arMsgMapTable[MID_MNY_P2P_CONNECTION_ABORT].pfMsgHndl = p2pFsmRunEventConnectionAbort; + arMsgMapTable[MID_MNY_P2P_MGMT_TX].pfMsgHndl = p2pFsmRunEventMgmtFrameTx; + arMsgMapTable[MID_MNY_P2P_BEACON_UPDATE].pfMsgHndl = p2pFsmRunEventBeaconUpdate; + arMsgMapTable[MID_MNY_P2P_BEACON_DEL].pfMsgHndl = p2pFsmRunEventBeaconAbort; + arMsgMapTable[MID_MNY_P2P_CHNL_REQ].pfMsgHndl = p2pFsmRunEventChannelRequest; + arMsgMapTable[MID_MNY_P2P_CHNL_ABORT].pfMsgHndl = p2pFsmRunEventChannelAbort; + arMsgMapTable[MID_MNY_P2P_GROUP_DISSOLVE].pfMsgHndl = p2pFsmRunEventDissolve; + arMsgMapTable[MID_MNY_P2P_MGMT_FRAME_REGISTER].pfMsgHndl = p2pFsmRunEventMgmtFrameRegister; + + return TRUE; + } + else { + ASSERT(FALSE); + return FALSE; + } +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* unregiester p2p pointer to wlan module +* +* +* \retval 1 Success +*/ +/*----------------------------------------------------------------------------*/ +BOOLEAN +p2pUnregisterToWlan( + P_GLUE_INFO_T prGlueInfo + ) +{ + + P_P2P_FUNCTION_LINKER prFuncLkr = (P_P2P_FUNCTION_LINKER)NULL; + extern P_APPEND_VAR_IE_ENTRY_T prTxProbRspIETableWIP2P; + extern MSG_HNDL_ENTRY_T arMsgMapTable[]; + + printk(KERN_INFO DRV_NAME "P2P UNregister to wlan\n"); + + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prAdapter); + + if(prGlueInfo) { + + prFuncLkr = &(prGlueInfo->prAdapter->rP2pFuncLkr); + + /*reset all p2p function linker pointer to NULL*/ + kalMemZero(prFuncLkr, sizeof(P2P_FUNCTION_LINKER)); + + prTxProbRspIETableWIP2P = NULL; + + /*set p2p MsgMapTable entry to mbox dummy*/ + arMsgMapTable[MID_P2P_SAA_FSM_START].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_P2P_SAA_FSM_ABORT].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_CNM_P2P_CH_GRANT].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_SCN_P2P_SCAN_DONE].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_SAA_P2P_JOIN_COMPLETE].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_FUN_SWITCH].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_DEVICE_DISCOVERY].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_CONNECTION_REQ].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_CONNECTION_ABORT].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_MGMT_TX].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_BEACON_UPDATE].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_BEACON_DEL].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_CHNL_REQ].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_CHNL_ABORT].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_GROUP_DISSOLVE].pfMsgHndl = mboxDummy; + arMsgMapTable[MID_MNY_P2P_MGMT_FRAME_REGISTER].pfMsgHndl = mboxDummy; + + return TRUE; + } + else { + ASSERT(FALSE); + return FALSE; + } + +} + + +UINT_8 g_aucBufIpAddr[32] = {0}; + +static void wlanP2PEarlySuspend(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; + + printk(KERN_INFO "*********p2pEarlySuspend************\n"); + + if(!wlanExportGlueInfo(&prGlueInfo)) { + printk(KERN_INFO "*********p2pEarlySuspend ignored************\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))){ + printk(KERN_INFO "ip is not avaliable.\n"); + return; + } + + // <4> copy the IPv4 address + kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); + printk(KERN_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 + // <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))){ + printk(KERN_INFO "ipv6 is not avaliable.\n"); + return; + } + // <6> copy the IPv6 address + kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); + printk(KERN_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))) { + } + +#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 + u4NumIPv6; + 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) ((UINT_32) prParamNetAddr + + (UINT_32) (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) ((UINT_32) prParamNetAddr + + (UINT_32) (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); + + if (rStatus != WLAN_STATUS_SUCCESS) { + printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus); + } + } +} + + +static void wlanP2PLateResume(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 + + printk(KERN_INFO "*********wlanP2PLateResume************\n"); + if(!wlanExportGlueInfo(&prGlueInfo)) { + printk(KERN_INFO "*********p2pLateResume ignored************\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))){ + printk(KERN_INFO "ip is not avaliable.\n"); + return; + } + + // <4> copy the IPv4 address + kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); + printk(KERN_INFO"ip is %d.%d.%d.%d\n", + ip[0],ip[1],ip[2],ip[3]); + +#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))){ + printk(KERN_INFO "ipv6 is not avaliable.\n"); + return; + } + // <6> copy the IPv6 address + kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); + printk(KERN_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); + + if (rStatus != WLAN_STATUS_SUCCESS) { + printk(KERN_INFO DRV_NAME"set HW pattern filter fail 0x%lx\n", rStatus); + } + } +} + +static struct early_suspend mt6620_p2p_early_suspend_desc = { + .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN, +}; + +static void p2p_early_suspend(struct early_suspend *h) +{ + printk(KERN_INFO "*********wlanP2P_early_suspend************\n"); + wlanP2PEarlySuspend(); +} + +static void p2p_late_resume(struct early_suspend *h) +{ + printk(KERN_INFO "*********wlanP2P_late_resume************\n"); + wlanP2PLateResume(); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 + ) +{ + if(prGlueInfo->prAdapter->fgIsP2PRegistered == TRUE) { + return FALSE; + } + else if(p2pRegisterToWlan(prGlueInfo) + && glRegisterP2P(prGlueInfo, ifname, (BOOLEAN)mode)) { + prGlueInfo->prAdapter->fgIsP2PRegistered = TRUE; + /*p2p is launched successfully*/ + + /* Here, we register the early suspend and resume callback */ + glRegisterEarlySuspend(&mt6620_p2p_early_suspend_desc, p2p_early_suspend, p2p_late_resume); + return TRUE; + } + return FALSE; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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) { + return FALSE; + } + else { + + glUnregisterEarlySuspend(&mt6620_p2p_early_suspend_desc); + + /*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); + p2pUnregisterToWlan(prGlueInfo); + /*p2p is removed successfully*/ + return TRUE; + } + return FALSE; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 __init initP2P(void) +{ + P_GLUE_INFO_T prGlueInfo; + + /*check interface name validation*/ + p2pCheckInterfaceName(); + + printk( KERN_INFO DRV_NAME "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; + + printk( 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() */ + +module_init(initP2P); +module_exit(exitP2P); + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_kal.c b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_kal.c new file mode 100755 index 000000000000..0c656128fff6 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/gl_p2p_kal.c @@ -0,0 +1,1509 @@ +/* +** $Id: @(#) gl_p2p_cfg80211.c@@ +*/ + +/*! \file gl_p2p_kal.c + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +/******************************************************************************* +* C O M P I L E 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 "p2p_precomp.h" + +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 + +/******************************************************************************* +* 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 +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 + ); + + +/******************************************************************************* +* 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="MACSTR, MAC2STR(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="MACSTR, MAC2STR(rPeerAddr)); + evt.data.length = strlen(aucBuffer); + + /* indicate in IWECUSTOM event */ + wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler, + IWEVCUSTOM, + &evt, + aucBuffer); + } + else { + ASSERT(0); + } + + return; +} /* 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); + + return; +} /* 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 + ) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo); + + prGlueInfo->prP2PInfo->u4CipherPairwise = u4Cipher; + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 + ) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo); + + 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 + ) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo); + + 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 + ) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo); + + 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 + ) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo); + + prGlueInfo->prP2PInfo->ucWSCRunning = ucWscMode; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief to get the status of WSC +* +* \param[in] +* prGlueInfo +* +* \return +*/ +/*----------------------------------------------------------------------------*/ +UINT_8 +kalP2PGetWscMode ( + IN P_GLUE_INFO_T prGlueInfo + ) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo); + + 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); + + return; +} + + +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); + + return; +} /* 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); + + return; +} /* 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); + + return; +} /* 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); + + return; +} /* 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); + + return; +} /* 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); + + return; +} /* end of kalP2PIndicateSDResponse() */ + + +struct net_device* +kalP2PGetDevHdlr( + P_GLUE_INFO_T prGlueInfo + ) +{ + ASSERT(prGlueInfo); + ASSERT(prGlueInfo->prP2PInfo); + 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); + return; +} /* 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, + 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->prDevHandler, //struct net_device * dev, + u8SeqNum, //u64 cookie, + prIEEE80211ChnlStruct, //struct ieee80211_channel * chan, + eChnlType, //enum nl80211_channel_type channel_type, + 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->prDevHandler, //struct net_device * dev, + prChnlReqInfo->u8Cookie, + prIEEE80211ChnlStruct, + eChnlType, + 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; + + do { + if (prGlueInfo == NULL) { + + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo; + + if (prGlueP2pInfo == NULL) { + ASSERT(FALSE); + break; + } + + + if (prGlueP2pInfo->prScanRequest) { + cfg80211_scan_done(prGlueP2pInfo->prScanRequest, + fgIsAbort); + + prGlueP2pInfo->prScanRequest = NULL; + } + + } 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; + + 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, TRACE, ("Unknown channel info\n")); + break; + } + + + //rChannelInfo.center_freq = nicChannelNum2Freq((UINT_32)prChannelInfo->ucChannelNum) / 1000; + + cfg80211_inform_bss_frame(prGlueP2pInfo->wdev.wiphy, //struct wiphy * wiphy, + prChannelEntry, + prBcnProbeRspFrame, + u4BufLen, + i4SignalStrength, + GFP_KERNEL); + + } while (FALSE); + + return; + +} /* 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. 0x%lx, 0x%lx, %ld.", prGlueInfo, pucFrameBuf, u4FrameLen)); + ASSERT(FALSE); + break; + } + + prGlueP2pInfo = prGlueInfo->prP2PInfo; + + cfg80211_mgmt_tx_status(prGlueP2pInfo->prDevHandler, //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: "MACSTR"\n", MAC2STR(prWlanHeader->aucAddr2))); +#endif + i4Freq = nicChannelNum2Freq(ucChnlNum) / 1000; + + cfg80211_rx_mgmt(prGlueP2pInfo->prDevHandler, //struct net_device * dev, + i4Freq, + prSwRfb->pvHeader, + prSwRfb->u2PacketLen, + GFP_KERNEL); + + } 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 + ) +{ + 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, + 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; + + do { + if ((prGlueInfo == NULL) || (prCliStaRec == NULL)) { + break; + } + + + prP2pGlueInfo = prGlueInfo->prP2PInfo; + + if (fgIsNew) { + rStationInfo.filled = 0; + 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; + + do { + if ((prP2pInfo == NULL) || (prChannelInfo == NULL)) { + break; + } + + + switch (prChannelInfo->eBand) { + case BAND_2G4: + prTargetChannelEntry = prP2pInfo->wdev.wiphy->bands[IEEE80211_BAND_2GHZ]->channels; + u4TblSize = prP2pInfo->wdev.wiphy->bands[IEEE80211_BAND_2GHZ]->n_channels; + break; + case BAND_5G: + prTargetChannelEntry = prP2pInfo->wdev.wiphy->bands[IEEE80211_BAND_5GHZ]->channels; + u4TblSize = prP2pInfo->wdev.wiphy->bands[IEEE80211_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 */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_ioctl.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_ioctl.h new file mode 100755 index 000000000000..dbcfd270b695 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_ioctl.h @@ -0,0 +1,1085 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/os/linux/include/gl_p2p_ioctl.h#7 $ +*/ + +/*! \file gl_p2p_ioctl.h + \brief This file is for custom ioctls for Wi-Fi Direct only +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_p2p_ioctl.h $ + * + * 02 23 2012 chinglan.wang + * [ALPS00240621] [Wifi P2P]Run Sigma tool of A69. Always run fail on 7.1.3. sniffer check Sta-IsActive-No-Frames-With-PowerMgmt-1 + * . + * + * 01 31 2012 yuche.tsai + * NULL + * Fix compile error & del beacon scenario. + * + * 01 26 2012 yuche.tsai + * NULL + * Fix compile warning. + * + * 01 16 2012 chinglan.wang + * NULL + * Update security code.. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Tethering for ICS code update. - fix KE when indicate Probe Request. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 01 09 2012 terry.wu + * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork + * cfg80211 integration for p2p network. + * + * 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 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 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 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 paramters + * + * 02 17 2011 wh.su + * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request + * adjust the set wsc ie structure. + * + * 01 05 2011 cp.wu + * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service Discovery + * ioctl implementations for P2P Service Discovery + * + * 12 22 2010 cp.wu + * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service Discovery + * 1. header file restructure for more clear module isolation + * 2. add function interface definition for implementing Service Discovery callbacks + * + * 12 15 2010 cp.wu + * NULL + * invoke nicEnableInterrupt() before leaving from wlanAdapterStart() + * + * 12 07 2010 cp.wu + * [WCXRP00000237] [MT6620 Wi-Fi][Wi-Fi Direct][Driver] Add interface for supporting service discovery + * define a pair of i/o control for multiplexing layer + * + * 11 04 2010 wh.su + * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID + * adding the p2p random ssid support. + * + * 10 20 2010 wh.su + * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group + * Add the code to support disconnect p2p group + * + * 09 21 2010 kevin.huang + * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface + * Isolate P2P related function for Hardware Software Bundle + * + * 09 10 2010 george.huang + * NULL + * update iwpriv LP related + * + * 09 07 2010 wh.su + * NULL + * adding the code for beacon/probe req/ probe rsp wsc ie at p2p. + * + * 08 25 2010 cp.wu + * NULL + * add netdev_ops(NDO) for linux kernel 2.6.31 or greater + * + * 08 20 2010 yuche.tsai + * NULL + * Refine a function parameter name. + * + * 08 19 2010 cp.wu + * NULL + * add set mac address interface for further possibilities of wpa_supplicant overriding interface address. + * + * 08 16 2010 george.huang + * NULL + * add wext handlers to link P2P set PS profile/ network address function (TBD) + * + * 08 16 2010 cp.wu + * NULL + * revised implementation of Wi-Fi Direct io controls. + * + * 08 12 2010 cp.wu + * NULL + * follow-up with ioctl interface update for Wi-Fi Direct application + * + * 08 06 2010 cp.wu + * NULL + * driver hook modifications corresponding to ioctl interface change. + * + * 08 03 2010 cp.wu + * NULL + * [Wi-Fi Direct] add framework for driver hooks + * + * 07 08 2010 cp.wu + * + * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. + * + * 06 06 2010 kevin.huang + * [WPD00003832][MT6620 5931] Create driver base + * [MT6620 5931] Create driver base + * + * 06 01 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * add ioctl to configure scan mode for p2p connection + * + * 05 31 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * add cfg80211 interface, which is to replace WE, for further extension + * + * 05 17 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * implement get scan result. + * + * 05 14 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * implement wireless extension ioctls in iw_handler form. + * + * 05 14 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well + * + * 05 11 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * p2p ioctls revised. + * + * 05 11 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * add ioctl for controlling p2p scan phase parameters + * +*/ + +#ifndef _GL_P2P_IOCTL_H +#define _GL_P2P_IOCTL_H + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 + #include + #include +#endif + +#include "wlan_oid.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +// (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 +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ +/* Macros used for cfg80211 */ +#define RATETAB_ENT(_rate, _rateid, _flags) \ + { \ + .bitrate = (_rate), \ + .hw_value = (_rateid), \ + .flags = (_flags), \ + } + +#define CHAN2G(_channel, _freq, _flags) \ + { \ + .band = IEEE80211_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ + } + +#define CHAN5G(_channel, _flags) \ + { \ + .band = IEEE80211_BAND_5GHZ, \ + .center_freq = 5000 + (5 * (_channel)), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ + } + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0) +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, + u8 *mac, + struct station_info *sinfo + ); + +int mtk_p2p_cfg80211_scan( + struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_scan_request *request + ); + +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_txpower( + struct wiphy *wiphy, + enum nl80211_tx_power_setting type, + int mbm + ); + +int mtk_p2p_cfg80211_get_txpower( + struct wiphy *wiphy, + int *dbm + ); + +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 net_device * dev, + struct ieee80211_channel * chan, + enum nl80211_channel_type channel_type, + unsigned int duration, + u64 * cookie + ); + +int +mtk_p2p_cfg80211_cancel_remain_on_channel( + struct wiphy * wiphy, + struct net_device * dev, + u64 cookie + ); + +int +mtk_p2p_cfg80211_mgmt_tx( + struct wiphy * wiphy, + struct net_device * dev, + struct ieee80211_channel * chan, + bool offchan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + unsigned int wait, + const u8 * buf, + size_t len, + u64 *cookie + ); + +int +mtk_p2p_cfg80211_deauth( + struct wiphy * wiphy, + struct net_device * dev, + struct cfg80211_deauth_request * req, + void * cookie + ); + + +int +mtk_p2p_cfg80211_disassoc( + struct wiphy * wiphy, + struct net_device * dev, + struct cfg80211_disassoc_request * req, + void * cookie + ); + +int +mtk_p2p_cfg80211_add_set_beacon( + struct wiphy *wiphy, + struct net_device *dev, + struct beacon_parameters *info + ); + +int +mtk_p2p_cfg80211_del_beacon( + struct wiphy * wiphy, + struct net_device * dev + ); + +int +mtk_p2p_cfg80211_del_station( + struct wiphy * wiphy, + struct net_device * dev, + u8 * mac + ); + +int +mtk_p2p_cfg80211_set_channel( + IN struct wiphy * wiphy, + IN struct net_device * dev, + IN struct ieee80211_channel * chan, + IN enum nl80211_channel_type channel_type + ); + +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 + ); + + +void +mtk_p2p_cfg80211_mgmt_frame_register( + IN struct wiphy *wiphy, + IN struct net_device *dev, + IN u16 frame_type, + IN bool reg + ); + +#if CONFIG_NL80211_TESTMODE +int +mtk_p2p_cfg80211_testmode_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/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_kal.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_kal.h new file mode 100755 index 000000000000..85de7564a080 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_kal.h @@ -0,0 +1,421 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/WIFI_P2P_DRIVER_V2_2/os/linux/include/gl_p2p_kal.h#3 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_p2p_kal.h $ + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 01 20 2012 chinglan.wang + * NULL + * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug.. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 "gl_p2p_ioctl.h" +#include "nic/p2p.h" + + +#if DBG + extern int allocatedMemSize; +#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 +******************************************************************************** +*/ + +/* 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 + ); + + +VOID +kalP2PGOStationUpdate( + IN P_GLUE_INFO_T prGlueInfo, + IN P_STA_RECORD_T prCliStaRec, + IN BOOLEAN fgIsNew + ); + + + + + + + + +#endif /* _GL_P2P_KAL_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_os.h b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_os.h new file mode 100755 index 000000000000..e37a1270236f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/p2p/os/linux/include/gl_p2p_os.h @@ -0,0 +1,206 @@ +/* +** $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. +*/ + + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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 wdev; + + struct cfg80211_scan_request *prScanRequest; + + UINT_64 u8Cookie; + + /* Generation for station list update. */ + INT_32 i4Generation; + + #endif + + /* Device statistics */ + struct net_device_stats rNetDevStats; + + /* glue layer variables */ + /*move to glueinfo->adapter*/ + // BOOLEAN fgIsRegistered; + 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]; + + 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 + +}; + + +BOOLEAN +p2pRegisterToWlan( + P_GLUE_INFO_T prGlueInfo + ); + +BOOLEAN +p2pUnregisterToWlan( + P_GLUE_INFO_T prGlueInfo + ); + +BOOLEAN +p2pLaunch( + P_GLUE_INFO_T prGlueInfo + ); + +BOOLEAN +p2pRemove( + P_GLUE_INFO_T prGlueInfo + ); + +BOOLEAN +glRegisterP2P( + P_GLUE_INFO_T prGlueInfo, + const char *prDevName, + BOOLEAN fgIsApMode + ); + +BOOLEAN +glUnregisterP2P( + P_GLUE_INFO_T prGlueInfo + ); + +BOOLEAN +p2pStopImmediate( + P_GLUE_INFO_T prGlueInfo + ); + + + +#endif diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/Makefile b/drivers/mtk_wcn_combo/drv_wlan/wlan/Makefile new file mode 100755 index 000000000000..c5add8fcfd75 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/Makefile @@ -0,0 +1,154 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. +# +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# --------------------------------------------------- +# Compile Options +# --------------------------------------------------- +ccflags-y += -DLINUX -DMT6620 +#for the kernel module inserted issue +ccflags-y += -fno-pic + +#MTK_WAPI_SUPPORT = yes + +ifeq ($(MTK_WAPI_SUPPORT), yes) + ccflags-y += -DCFG_SUPPORT_WAPI=1 +else + ccflags-y += -DCFG_SUPPORT_WAPI=0 +endif + +ifeq ($(HAVE_XLOG_FEATURE), yes) + ccflags-y += -DCFG_SUPPORT_XLOG=1 +else + ccflags-y += -DCFG_SUPPORT_XLOG=0 +endif + +#ifeq ($(CONFIG_MTK_COMBO_WIFI_HIF_SDIO1), y) +# ccflags-y += -D_HIF_SDIO=1 +#endif +ccflags-y += -D_HIF_SDIO=1 + +ccflags-y += -DDBG=0 +#ccflags-y += -DDBG=1 +ccflags-y += -I$(src)/os -I$(src)/os/linux/include -I$(src)/os/linux/hif/sdio/include +ccflags-y += -I$(src)/include -I$(src)/include/nic -I$(src)/include/mgmt + +ccflags-y += -O2 +obj-$(CONFIG_MTK_COMBO_WIFI) += wlan.o + +# --------------------------------------------------- +# Directory List +# --------------------------------------------------- +COMMON_DIR := common/ +OS_DIR := ./os/linux/ +HIF_DIR := os/linux/hif/sdio/ +NIC_DIR := nic/ +MGMT_DIR := mgmt/ +WAPI_DIR :=./os/linux/ + +ifeq ($(MTK_WAPI_SUPPORT), yes) +always := $(shell cp -f $(WAPI_DIR)gl_sec.o.new $(WAPI_DIR)gl_sec.o) +always := $(touch $(OS_DIR)gl_sec.o) +endif +always := $(@echo *********** $$(src)) + + +# --------------------------------------------------- +# Objects List +# --------------------------------------------------- + +COMMON_OBJS := $(COMMON_DIR)dump.o \ + $(COMMON_DIR)wlan_lib.o \ + $(COMMON_DIR)wlan_oid.o \ + $(COMMON_DIR)wlan_bow.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)platform.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)roaming_fsm.o + +ifeq ($(MTK_WAPI_SUPPORT), yes) +MGMT_OBJS += $(MGMT_DIR)wapi.o +OS_OBJS += $(OS_DIR)gl_sec.o +endif + +ifeq ($(WLAN_PROC), y) +OS_OBJS += gl_proc.o +endif + +HIF_OBJS := $(HIF_DIR)arm.o \ + $(HIF_DIR)sdio.o + +wlan-objs += $(COMMON_OBJS) +wlan-objs += $(NIC_OBJS) +wlan-objs += $(OS_OBJS) +wlan-objs += $(HIF_OBJS) +wlan-objs += $(MGMT_OBJS) + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/common/dump.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/dump.c new file mode 100755 index 000000000000..482cf7aacf3a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/dump.c @@ -0,0 +1,583 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/common/dump.c#1 $ +*/ + +/*! \file "dump.c" + \brief Provide memory dump function for debugging. + + Provide memory dump function for debugging. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +******************************************************************************** +*/ +#if DBG +/*----------------------------------------------------------------------------*/ +/*! +* \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: %08lx, Length: %ld\n", (UINT_32)pucStartAddr, u4Length); + + while (u4Length > 0) { + if (u4Length >= 16) { + LOG_FUNC("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", + (UINT_32)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("(%08lx) %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0]); + break; + case 2: + LOG_FUNC("(%08lx) %02x %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1]); + break; + case 3: + LOG_FUNC("(%08lx) %02x %02x %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2]); + break; + case 4: + LOG_FUNC("(%08lx) %02x %02x %02x %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3]); + break; + case 5: + LOG_FUNC("(%08lx) %02x %02x %02x %02x %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4]); + break; + case 6: + LOG_FUNC("(%08lx) %02x %02x %02x %02x %02x %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5]); + break; + case 7: + LOG_FUNC("(%08lx) %02x %02x %02x %02x %02x %02x %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5], pucStartAddr[ 6]); + break; + case 8: + LOG_FUNC("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5], pucStartAddr[ 6], pucStartAddr[ 7]); + break; + case 9: + LOG_FUNC("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x\n", + (UINT_32)pucStartAddr, + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5], pucStartAddr[ 6], pucStartAddr[ 7], + pucStartAddr[ 8]); + break; + case 10: + LOG_FUNC("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x\n", + (UINT_32)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("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x\n", + (UINT_32)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("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", + (UINT_32)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("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x\n", + (UINT_32)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("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x\n", + (UINT_32)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("(%08lx) %02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x\n", + (UINT_32)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"); + + return; +} /* 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: %08lx, Length: %ld\n", (UINT_32)pu4StartAddr, u4Length); + + if (IS_NOT_ALIGN_4((UINT_32)pu4StartAddr)) { + UINT_32 u4ProtrudeLen = sizeof(UINT_32) - ((UINT_32)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("(%08lx) %02x------\n", + (UINT_32)pu4StartAddr, + pucAddr[0]); + break; + case 2: + LOG_FUNC("(%08lx) %02x%02x----\n", + (UINT_32)pu4StartAddr, + pucAddr[1], pucAddr[0]); + break; + case 3: + LOG_FUNC("(%08lx) %02x%02x%02x--\n", + (UINT_32)pu4StartAddr, + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + default: + break; + } + + u4Length -= u4ProtrudeLen; + pu4StartAddr = (PUINT_32)((UINT_32)pu4StartAddr + u4ProtrudeLen); + } + + while (u4Length > 0) { + if (u4Length >= 16) { + LOG_FUNC("(%08lx) %08lx %08lx %08lx %08lx\n", + (UINT_32)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("(%08lx) ------%02x\n", + (UINT_32)pu4StartAddr, + pucAddr[0]); + break; + case 2: + pucAddr = (PUINT_8) &pu4StartAddr[0]; + LOG_FUNC("(%08lx) ----%02x%02x\n", + (UINT_32)pu4StartAddr, + pucAddr[1], pucAddr[0]); + break; + case 3: + pucAddr = (PUINT_8) &pu4StartAddr[0]; + LOG_FUNC("(%08lx) --%02x%02x%02x\n", + (UINT_32)pu4StartAddr, + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + case 4: + LOG_FUNC("(%08lx) %08lx\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0]); + break; + case 5: + pucAddr = (PUINT_8) &pu4StartAddr[1]; + LOG_FUNC("(%08lx) %08lx ------%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], + pucAddr[0]); + break; + case 6: + pucAddr = (PUINT_8) &pu4StartAddr[1]; + LOG_FUNC("(%08lx) %08lx ----%02x%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], + pucAddr[1], pucAddr[0]); + break; + case 7: + pucAddr = (PUINT_8) &pu4StartAddr[1]; + LOG_FUNC("(%08lx) %08lx --%02x%02x%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + case 8: + LOG_FUNC("(%08lx) %08lx %08lx\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1]); + break; + case 9: + pucAddr = (PUINT_8) &pu4StartAddr[2]; + LOG_FUNC("(%08lx) %08lx %08lx ------%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pucAddr[0]); + break; + case 10: + pucAddr = (PUINT_8) &pu4StartAddr[2]; + LOG_FUNC("(%08lx) %08lx %08lx ----%02x%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pucAddr[1], pucAddr[0]); + break; + case 11: + pucAddr = (PUINT_8) &pu4StartAddr[2]; + LOG_FUNC("(%08lx) %08lx %08lx --%02x%02x%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + case 12: + LOG_FUNC("(%08lx) %08lx %08lx %08lx\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2]); + break; + case 13: + pucAddr = (PUINT_8) &pu4StartAddr[3]; + LOG_FUNC("(%08lx) %08lx %08lx %08lx ------%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], + pucAddr[0]); + break; + case 14: + pucAddr = (PUINT_8) &pu4StartAddr[3]; + LOG_FUNC("(%08lx) %08lx %08lx %08lx ----%02x%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], + pucAddr[1], pucAddr[0]); + break; + case 15: + pucAddr = (PUINT_8) &pu4StartAddr[3]; + LOG_FUNC("(%08lx) %08lx %08lx %08lx --%02x%02x%02x\n", + (UINT_32)pu4StartAddr, + pu4StartAddr[0], pu4StartAddr[1], pu4StartAddr[2], + pucAddr[2], pucAddr[1], pucAddr[0]); + break; + default: + break; + } + u4Length = 0; + } + } + + return; +} /* end of dumpMemory32() */ +#elif CFG_SUPPORT_XLOG + +/*----------------------------------------------------------------------------*/ +/*! +* \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 UINT_32 log_level, + IN PUINT_8 pucStartAddr, + IN UINT_32 u4Length + ) +{ + ASSERT(pucStartAddr); + + if (log_level == ANDROID_LOG_ERROR) { + xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, "DUMP8 ADDRESS: %08lx, Length: %ld\n", (UINT_32)pucStartAddr, u4Length); + } + else if (log_level == ANDROID_LOG_WARN) { + xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, "DUMP8 ADDRESS: %08lx, Length: %ld\n", (UINT_32)pucStartAddr, u4Length); + } + else if (log_level == ANDROID_LOG_INFO) { + xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, "DUMP8 ADDRESS: %08lx, Length: %ld\n", (UINT_32)pucStartAddr, u4Length); + } + else if (log_level == ANDROID_LOG_DEBUG) { + xlog_printk(ANDROID_LOG_DEBUG, XLOG_TAG, "DUMP8 ADDRESS: %08lx, Length: %ld\n", (UINT_32)pucStartAddr, u4Length); + } + else if (log_level == ANDROID_LOG_VERBOSE) { + xlog_printk(ANDROID_LOG_VERBOSE, XLOG_TAG, "DUMP8 ADDRESS: %08lx, Length: %ld\n", (UINT_32)pucStartAddr, u4Length); + } + + while (u4Length > 0) { + if (u4Length >= 16) { + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x %02x\n", + 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: + XLOG_FUNC(log_level, "%02x\n", + pucStartAddr[ 0]); + break; + case 2: + XLOG_FUNC(log_level, "%02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1]); + break; + case 3: + XLOG_FUNC(log_level, "%02x %02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2]); + break; + case 4: + XLOG_FUNC(log_level, "%02x %02x %02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3]); + break; + case 5: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4]); + break; + case 6: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5]); + break; + case 7: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5], pucStartAddr[ 6]); + break; + case 8: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5], pucStartAddr[ 6], pucStartAddr[ 7]); + break; + case 9: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5], pucStartAddr[ 6], pucStartAddr[ 7], + pucStartAddr[ 8]); + break; + case 10: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x\n", + pucStartAddr[ 0], pucStartAddr[ 1], pucStartAddr[ 2], pucStartAddr[ 3], + pucStartAddr[ 4], pucStartAddr[ 5], pucStartAddr[ 6], pucStartAddr[ 7], + pucStartAddr[ 8], pucStartAddr[ 9]); + break; + case 11: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x\n", + 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: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x\n", + 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: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x\n", + 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: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x\n", + 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: + XLOG_FUNC(log_level, "%02x %02x %02x %02x %02x %02x %02x %02x - %02x %02x %02x %02x %02x %02x %02x\n", + 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; + } + } + + + return; +} /* end of dumpMemory8() */ +#endif /* DBG */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_bow.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_bow.c new file mode 100755 index 000000000000..b9f52a7ad5c0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_bow.c @@ -0,0 +1,3962 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/common/wlan_bow.c#2 $ +*/ + +/*! \file wlan_bow.c + \brief This file contains the 802.11 PAL commands processing routines for + MediaTek Inc. 802.11 Wireless LAN Adapters. +*/ + +/****************************************************************************** +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************* +*/ + +/****************************************************************************** +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************* +*/ + +/* +** $Log: wlan_bow.c $ + * + * 02 16 2012 chinghwa.yu + * [ALPS00238061] [Need Patch] [Volunteer Patch] Support BOW for 5GHz band, remove debug message. + * + * 02 16 2012 chinghwa.yu + * [ALPS00238061] [Need Patch] [Volunteer Patch] Support BOW for 5GHz band. + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 01 15 2012 yuche.tsai + * NULL + * Fix wrong basic rate issue. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 06 29 2011 terry.wu + * NULL + * Add BoW 11n support. + * + * 06 29 2011 terry.wu + * NULL + * Sync BoW code to Trunk. + * + * 06 23 2011 cp.wu + * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module + * follow-ups for frequency-shifted WAPI AP support + * + * 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. + * + * 04 29 2011 chinghwa.yu + * [WCXRP00000065] Update BoW design and settings + * Use kalMemAlloc for allocating BOW event temp buffer. + * + * 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 + * 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 + +#if CFG_BOW_TEST +extern UINT_32 g_arBowRevPalPacketTime[32]; +#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 +******************************************************************************* +*/ + +static UINT_32 g_u4LinkCount = 0; +static UINT_32 g_u4Beaconing = 0; +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); + + 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, EVENT, ("bowCmdGetMacStatus, Get preferred channel.\n")); +#endif + + /*printk("bowCmdGetMacStatus, Get preferred channel % x.\n", ucPrimaryChannel);*/ + + prMacStatus->ucNumOfChannel = 1; + prMacStatus->arChannelList[0].ucChannelBand = eBand; + prMacStatus->arChannelList[0].ucChannelNum = ucPrimaryChannel; + } + else + { +#if CFG_BOW_TEST + DBGLOG(BOW, EVENT, ("bowCmdGetMacStatus, Get channel list. Current number of channel, %d.\n", ucNumOfChannel)); +#endif + + rlmDomainGetChnlList(prAdapter, BAND_2G4, MAX_BOW_NUMBER_OF_CHANNEL_2G4, &ucNumOfChannel, aucChannelList); + + if (ucNumOfChannel > 0) { + for (idx = 0; idx < ucNumOfChannel/*MAX_BOW_NUMBER_OF_CHANNEL_2G4*/; idx++) + { + prMacStatus->arChannelList[idx].ucChannelBand = aucChannelList[idx].eBand; + prMacStatus->arChannelList[idx].ucChannelNum = aucChannelList[idx].ucChannelNum; + } + + prMacStatus->ucNumOfChannel = ucNumOfChannel; + } + + rlmDomainGetChnlList(prAdapter, BAND_5G, MAX_BOW_NUMBER_OF_CHANNEL_5G, &ucNumOfChannel, aucChannelList); + + if (ucNumOfChannel > 0) { + for (idx = 0; idx < ucNumOfChannel/*MAX_BOW_NUMBER_OF_CHANNEL_5G*/; idx++) + { + prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelBand = aucChannelList[idx].eBand; + prMacStatus->arChannelList[prMacStatus->ucNumOfChannel + idx].ucChannelNum = aucChannelList[idx].ucChannelNum; + } + + prMacStatus->ucNumOfChannel = prMacStatus->ucNumOfChannel + ucNumOfChannel; + + } + } + + /*printk("prMacStatus->ucNumOfChannel, eBand, prMacStatus->arChannelList, %x, %x, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", + prMacStatus->ucNumOfChannel, + prMacStatus->arChannelList[0].ucChannelBand, + 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);*/ + + +#if CFG_BOW_TEST + DBGLOG(BOW, EVENT, ("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, EVENT, ("prMacStatus->ucNumOfChannel, eBand, prMacStatus->arChannelList, %x, %x, %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x.\n", + prMacStatus->ucNumOfChannel, + prMacStatus->arChannelList[0].ucChannelBand, + 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, EVENT, ("prMacStatus->ucNumOfChannel, %x.\n", prMacStatus->ucNumOfChannel)); + DBGLOG(BOW, EVENT, ("prMacStatus->arChannelList[0].ucChannelBand, %x.\n", prMacStatus->arChannelList[0].ucChannelBand)); + DBGLOG(BOW, EVENT, ("prMacStatus->arChannelList[0].ucChannelNum, %x.\n", prMacStatus->arChannelList[0].ucChannelNum)); + DBGLOG(BOW, EVENT, ("prMacStatus->ucAvailability, %x.\n", prMacStatus->ucAvailability)); + DBGLOG(BOW, EVENT, ("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; + } + + /*printk("bowCmdSetupConnection.\n"); + printk("rCmdBtOverWifi Channel Band - 0x%x.\n", rCmdBtOverWifi.ucChannelBand); + printk("rCmdBtOverWifi Channel Number - 0x%x.\n", rCmdBtOverWifi.ucChannelNum); + printk("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]); + printk("rCmdBtOverWifi Beacon interval - 0x%x.\n", rCmdBtOverWifi.u2BeaconInterval); + printk("rCmdBtOverWifi Timeout activity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutDiscovery); + printk("rCmdBtOverWifi Timeout inactivity - 0x%x.\n", rCmdBtOverWifi.ucTimeoutInactivity); + printk("rCmdBtOverWifi Role - 0x%x.\n", rCmdBtOverWifi.ucRole); + printk("rCmdBtOverWifi PAL capability - 0x%x.\n", rCmdBtOverWifi.PAL_Capabilities); + printk("rCmdBtOverWifi Max Tx power - 0x%x.\n", rCmdBtOverWifi.cMaxTxPower);*/ + + +#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; + + 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, + (UINT_32)NULL); + + cnmTimerInitTimer(prAdapter, + &prBowFsmInfo->rChGrantedTimer, + (PFN_MGMT_TIMEOUT_FUNC)bowChGrantedTimeout, + (UINT_32)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; + } + else + { + 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); + 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); + 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); + 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; + BOOL 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); + 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); + + /*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; + 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); + 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); + 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); + 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); + 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))); + + return; +} + + +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); + + } + + return; +} + + +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 + prBssInfo->ucPhyTypeSet = prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; /* Depend on eBand */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + + 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) + { + prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; /* Depend on eBand */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + + prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; //RATE_SET_ERP; + prBssInfo->u2OperationalRateSet = RATE_SET_ERP; + prBssInfo->ucNonHTBasicPhyType = PHY_TYPE_ERP_INDEX; + } + else + { + //prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11BG; /* Depend on eBand */ + //prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + prBssInfo->ucPhyTypeSet = PHY_TYPE_SET_802_11A; /* Depend on eBand */ + prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + + //prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_ERP; //RATE_SET_ERP; + //prBssInfo->u2OperationalRateSet = RATE_SET_ERP; + + prBssInfo->u2BSSBasicRateSet = BASIC_RATE_SET_OFDM; //RATE_SET_ERP; + 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 { + //bowRequestCh(prAdapter); + } +#endif + return; +} + +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; + } + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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)((UINT_32)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 UINT_32 u4Param + ) +{ + 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 */ + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + } + else + { + 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 + } + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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); + + 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)); + printk("BoW trigger SAA ["MACSTR"]\n", MAC2STR(prStaRec->aucMacAddr)); +#endif + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (P_MSG_HDR_T) prJoinReqMsg, + MSG_SEND_METHOD_BUF); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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 avaliable 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")); + printk("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)); + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indiate 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")); + printk("BoW AAA TxFail, target state %d\n", prStaRec->ucStaState+1); +#endif + + prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); + bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This function will indiate 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")); + printk("BoW AAA complete ["MACSTR"]\n", MAC2STR(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 = 0; + + 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); + 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 avaliable highest rate*/ + if(prStaRec->u2DesiredNonHTRateSet == 0) { + UINT_8 ucHighestRateIndex; + if (rateGetHighestRateIndexFromRateSet(prBowBssInfo->u2OperationalRateSet, &ucHighestRateIndex)) { + prStaRec->u2DesiredNonHTRateSet = BIT(ucHighestRateIndex); + } else { + /*If no avaliable 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 = 0; + + /* 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. + */ + ASSERT(prStaRec); + 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 + printk("BoW Channel [GIVE UP:%d]\n", ucTokenID); + printk("[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 + printk("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); + } + + return; +} /* 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 + printk("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 + prMsgChReq->ucPrimaryChannel = prBowFsmInfo->ucPrimaryChannel; //prBowFsmInfo->prTargetBssDesc->ucChannelNum; + prMsgChReq->eRfSco = CHNL_EXT_SCN; //prBowFsmInfo->prTargetBssDesc->eSco; + prMsgChReq->eRfBand = prBowFsmInfo->eBand; //prBowFsmInfo->prTargetBssDesc->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 + printk("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); + } + + return; +} /* 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 UINT_32 u4Param + ) +{ + P_BOW_FSM_INFO_T prBowFsmInfo; + ENUM_BOW_DEVICE_STATE eFsmState; + + ASSERT(prAdapter); + + prBowFsmInfo = &(prAdapter->rWifiVar.rBowFsmInfo); + +#if CFG_BOW_TEST + printk("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)); + printk("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 + printk("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)); + printk("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 + printk("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/mtk_wcn_combo/drv_wlan/wlan/common/wlan_lib.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_lib.c new file mode 100755 index 000000000000..3d4528f3e715 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_lib.c @@ -0,0 +1,4934 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/common/wlan_lib.c#4 $ +*/ +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ +/* +** $Log: wlan_lib.c $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 15 2012 yuche.tsai + * NULL + * Fix wrong basic rate issue. + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 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 25 2011 cp.wu + * [WCXRP00001057] [MT6620 Wi-Fi][Driver][Firmware] Ensure no pending interrupt status bits remained while switching from RAM code to ROM code + * 1. [FW] always clear all pending messages while leaving from RAM code section. + * 2. [DRV] clear interrupt then wait for RDY bit de-assertion + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 while tearing down a station connection. + * + * 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 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 + * check-in missed file. + * + * 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 + * . + * + * 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 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) Chnage 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 adress & 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 +}; + +#if QM_TEST_MODE +extern QUE_MGT_T g_rQM; +#endif +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ +BOOLEAN fgIsBusAccessFailed = FALSE; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +// 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 +******************************************************************************** +*/ +/*----------------------------------------------------------------------------*/ +/*! +* \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 */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + } + +#if QM_TEST_MODE + g_rQM.prAdapter = prAdpater; +#endif + 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)); + + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +#if (defined(MT5931) && (!CFG_SUPPORT_BCM_BWCS)) + PARAM_PTA_IPC_T rBwcsPta; + UINT_32 u4SetInfoLen; +#endif + + ASSERT(prAdapter); + + DEBUGFUNC("wlanAdapterStart"); + + //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; + + do { + if ( (u4Status = nicAllocateAdapterMemory(prAdapter)) != WLAN_STATUS_SUCCESS ) { + DBGLOG(INIT, ERROR, ("nicAllocateAdapterMemory Error!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + + prAdapter->u4OsPacketFilter = PARAM_PACKET_FILTER_SUPPORTED; + +#if defined(MT6620) || defined(MT6628) + DBGLOG(INIT, TRACE, ("wlanAdapterStart(): Acquiring LP-OWN\n")); + 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; + break; + } + + //4 <1> Initialize the Adapter + if ( (u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS ) { + DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } +#endif + + //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 defined(MT6620) || defined(MT6628) + if (pvFwImageMapFile) { + /* 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) { + 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(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!\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, + 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) { + 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 + } + else { + DBGLOG(INIT, ERROR, ("No Firmware found!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + + /* 4. send Wi-Fi Start command */ + #if CFG_OVERRIDE_FW_START_ADDRESS + wlanConfigWifiFunc(prAdapter, + TRUE, + prRegInfo->u4StartAddress); + #else + wlanConfigWifiFunc(prAdapter, + FALSE, + 0); + #endif + #elif defined(MT5931) + if (pvFwImageMapFile) { + DBGLOG(INIT, TRACE, ("Download Address: 0x%08X\n", prRegInfo->u4LoadAddress)); + DBGLOG(INIT, TRACE, ("Firmware Length: 0x%08X\n", u4FwImageFileLength)); + + do { +#if CFG_SUPPORT_WHOLE_CHIP_RESET +#define RESET_RDY_INTERVAL (120) + + /* 1.0 whole-chip reset except HIFSYS */ + HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_CHIP_RST); + HAL_MCR_WR(prAdapter, MCR_WMCSR, 0); + + /* 1.0.1 delay for EEIF ready */ + kalMsleep(RESET_RDY_INTERVAL); +#endif + + /* 1.1 wait for INIT_RDY */ + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); + + if (u4Value & WMCSR_INI_RDY) { + DBGLOG(INIT, TRACE, ("INIT-RDY detected\n")); + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for Init Ready bit: Timeout\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + + if(u4Status != WLAN_STATUS_SUCCESS) { + break; + } + + /* 1.2 set KSEL/FLEN */ + HAL_MCR_WR(prAdapter, MCR_FWCFG, u4FwImageFileLength >> 6); + + /* 1.3 enable FWDL_EN */ + HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_FWDLEN); + + /* 1.4 wait for PLL_RDY */ + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); + + if (u4Value & WMCSR_PLLRDY) { + DBGLOG(INIT, TRACE, ("PLL-RDY detected\n")); + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for PLL Ready bit: Timeout\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + + if(u4Status != WLAN_STATUS_SUCCESS) { + break; + } + + /* 2.1 turn on HIFSYS firmware download mode */ + HAL_MCR_WR(prAdapter, MCR_FWDLSR, FWDLSR_FWDL_MODE); + + /* 2.2 set starting address */ + u4FwLoadAddr = prRegInfo->u4LoadAddress; + HAL_MCR_WR(prAdapter, MCR_FWDLDSAR, u4FwLoadAddr); + + /* 3. upload firmware */ + 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; + } + } + + if(u4Status != WLAN_STATUS_SUCCESS) { + break; + } + + /* 4.1 poll FWDL_OK & FWDL_FAIL bits */ + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); + + if (u4Value & WMCSR_DL_OK) { + DBGLOG(INIT, TRACE, ("DL_OK detected\n")); + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE + || (u4Value & WMCSR_DL_FAIL)) { + DBGLOG(INIT, ERROR, ("DL_FAIL detected: 0x%08X\n", u4Value)); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for DL_OK/DL_FAIL bit: Timeout\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + + if(u4Status != WLAN_STATUS_SUCCESS) { + break; + } + + /* 4.2 turn off HIFSYS download mode */ + HAL_MCR_WR(prAdapter, MCR_FWDLSR, 0); + + } while (FALSE); + + if(u4Status != WLAN_STATUS_SUCCESS) { + break; + } + + /* 5. disable interrupt */ + nicDisableInterrupt(prAdapter); + } + else { + DBGLOG(INIT, ERROR, ("No Firmware found!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + #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; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + UINT_32 u4MailBox0; + + nicGetMailbox(prAdapter, 0, &u4MailBox0); + DBGLOG(INIT, ERROR, ("Waiting for Ready bit: Timeout, ID=%d\n", + (u4MailBox0 & 0x0000FFFF))); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + +#if defined(MT5931) + // Acquire LP-OWN + DBGLOG(INIT, TRACE, ("wlanAdapterStart(): Acquiring LP-OWN\n")); + 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; + break; + } + + //4 <1> Initialize the Adapter + if ( (u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS ) { + DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + + /* post initialization for MT5931 due to some CR is only accessible after driver own */ + nicRxPostInitialize(prAdapter); +#endif + + 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); + +#if CFG_SUPPORT_OSC_SETTING && defined(MT5931) + wlanSetMcuOscStableTime(prAdapter, 0); +#endif + + /* 3. query for permanent address by polling */ + wlanQueryPermanentAddress(prAdapter); + +#if (CFG_SUPPORT_NIC_CAPABILITY == 1) + /* 4. query for NIC capability */ + wlanQueryNicCapability(prAdapter); +#endif + + /* 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) { + break; + } + + /* OID timeout timer initialize */ + cnmTimerInitTimer(prAdapter, + &prAdapter->rOidTimeoutTimer, + (PFN_MGMT_TIMEOUT_FUNC)wlanReleasePendingOid, + (UINT_32)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; + +#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 + +#if (defined(MT5931) && (!CFG_SUPPORT_BCM_BWCS)) + //Enable DPD calibration. + rBwcsPta.u.aucBTPParams[0] = 0x00; + rBwcsPta.u.aucBTPParams[1] = 0x01; + rBwcsPta.u.aucBTPParams[2] = 0x00; + rBwcsPta.u.aucBTPParams[3] = 0x80; + + wlanoidSetBT(prAdapter, + (PVOID)&rBwcsPta, + sizeof(PARAM_PTA_IPC_T), + &u4SetInfoLen); +#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 + nicReleaseAdapterMemory(prAdapter); + } + + 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) */ + 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) { + break; + } + else { + i++; + kalMsleep(10); + } + } + } + + /* 4. Set Onwership to F/W */ + nicpmSetFWOwn(prAdapter, FALSE); + + 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 */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +BOOL +wlanISR ( + IN P_ADAPTER_T prAdapter, + IN BOOLEAN fgGlobalIntrCtrl + ) +{ + ASSERT(prAdapter); + + if (fgGlobalIntrCtrl) { + nicDisableInterrupt(prAdapter); + + //wlanIST(prAdapter); + } + + return TRUE; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + nicProcessIST(prAdapter); + + nicEnableInterrupt(prAdapter); + + RECLAIM_POWER_CONTROL_TO_PM(prAdapter, FALSE); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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(); + + ASSERT(prAdapter); + ASSERT(prCmdQue); + + prTempCmdQue = &rTempCmdQue; + prMergeCmdQue = &rMergeCmdQue; + prStandInCmdQue = &rStandInCmdQue; + + QUEUE_INITIALIZE(prTempCmdQue); + QUEUE_INITIALIZE(prMergeCmdQue); + QUEUE_INITIALIZE(prStandInCmdQue); + + //4 <1> Move whole list of CMD_INFO to temp queue + 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 + QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T); + while(prQueueEntry) { + prCmdInfo = (P_CMD_INFO_T)prQueueEntry; + + 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) { + wlanReleaseCommand(prAdapter, prCmdInfo); + } + else if(eFrameAction == FRAME_ACTION_QUEUE_PKT) { + 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); + break; + } + else if(rStatus == WLAN_STATUS_PENDING) { + // command packet which needs further handling upon 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 { + P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)prQueueEntry; + + if (rStatus == WLAN_STATUS_SUCCESS) { + if (prCmdInfo->pfCmdDoneHandler) { + prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prCmdInfo->pucInfoBuffer); + } + } + else { + if (prCmdInfo->fgIsOid) { + kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, prCmdInfo->u4SetInfoLen, rStatus); + } + } + + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + } + } + else { + 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); + 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 informations 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; + + ASSERT(prAdapter); + ASSERT(prCmdInfo); + 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; + + // <1.2> Check if pending packet or resource was exhausted + if ((rStatus = nicTxAcquireResource(prAdapter, ucTC)) == 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) { + HAL_MCR_WR(prAdapter, + (prCmdAccessReg->u4Address & BITS(2,31)), //address is in DWORD unit + prCmdAccessReg->u4Data); + } + else { + P_CMD_ACCESS_REG prEventAccessReg; + UINT_32 u4Address; + + u4Address = prCmdAccessReg->u4Address; + prEventAccessReg = (P_CMD_ACCESS_REG)prCmdInfo->pucInfoBuffer; + prEventAccessReg->u4Address = u4Address; + + HAL_MCR_RD(prAdapter, + prEventAccessReg->u4Address & BITS(2,31), //address is in DWORD unit + &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) { + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + WLAN_STATUS_FAILURE); + } + break; + + case COMMAND_TYPE_SECURITY_FRAME: + 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: + ASSERT(0); + break; + } + + 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 UINT_32 u4Data + ) +{ + 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); + + 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; + + if (prCmdInfo->fgIsOid) { + 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); + + // 2: Clear pending OID in glue layer command queue + kalOidCmdClearance(prAdapter->prGlueInfo); + + // 3: Clear pending OID queued in pvOidEntry with REQ_FLAG_OID set + kalOidClearance(prAdapter->prGlueInfo); + + } while(FALSE); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + + 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); + + return; +} /* 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); + + 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)) { + } +#endif + } + + 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; + } + nicRxReturnRFB(prAdapter, prSwRfb); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 + if (prAdapter->u4PsCurrentMeasureEn && + (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) { + return WLAN_STATUS_SUCCESS; // note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking OIDs during current measurement ?? + } + +#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 + if (prAdapter->u4PsCurrentMeasureEn && + (prAdapter->prGlueInfo->eParamMediaStateIndicated == PARAM_MEDIA_STATE_CONNECTED)) { + return WLAN_STATUS_SUCCESS; // note: return WLAN_STATUS_FAILURE or WLAN_STATUS_SUCCESS for blocking OIDs during current measurement ?? + } + +#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) == WLAN_STATUS_RESOURCES) { + if (nicTxPollingResource(prAdapter, ucTC) != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR,("Fail to get TX resource return within timeout\n")); + status = WLAN_STATUS_FAILURE; + break; + } + else { + 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) == 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 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 + ) +{ + #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; + + 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) == 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; + } + else { + 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; + + #elif defined(MT5931) + + UINT_32 i, u4Value; + P_HIF_HW_TX_HEADER_T prHifTxHeader; + + WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + ASSERT(pucImgSecBuf); + ASSERT(u4ImgSecSize <= CMD_PKT_SIZE_FOR_IMAGE); + + DEBUGFUNC("wlanImageSectionDownload"); + DBGLOG(INIT, TRACE, ("Destination: 0x%08X / Length: 0x%08X\n", u4DestAddr, u4ImgSecSize)); + + if (u4ImgSecSize == 0) { + return WLAN_STATUS_SUCCESS; + } + + // 1. Use TX coalescing buffer + prHifTxHeader = (P_HIF_HW_TX_HEADER_T) prAdapter->pucCoalescingBufCached; + + // 2. Setup HIF_TX_HEADER + prHifTxHeader->u2TxByteCount = (UINT_16)(ALIGN_4(sizeof(HIF_HW_TX_HEADER_T) + u4ImgSecSize)); + prHifTxHeader->ucEtherTypeOffset = 0; + prHifTxHeader->ucCSflags = 0; + + // 3. Copy payload + kalMemCopy(prHifTxHeader->aucBuffer, pucImgSecBuf, u4ImgSecSize); + + // 3.1 add 4-bytes zero tail + kalMemZero(&(prHifTxHeader->aucBuffer[ALIGN_4(u4ImgSecSize)]), sizeof(HIF_HW_TX_HEADER_T)); + + // 4. Poll til FWDL_RDY = 1 + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_FWDLSR, &u4Value); + + if (u4Value & FWDLSR_FWDL_RDY) { + DBGLOG(INIT, TRACE, ("FWDL_RDY detected\n")); + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for FWDL_RDY: Timeout (0x%08X)\n", u4Value)); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + + // 5. Send firmware + HAL_PORT_WR(prAdapter, + MCR_FWDLDR, + prHifTxHeader->u2TxByteCount, + (PUINT_8)prHifTxHeader, + prAdapter->u4CoalescingBufCachedSize); + + return u4Status; + + #endif +} + +#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) == 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; + } + else { + 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; + DBGLOG(INIT, ERROR, ("Bus error(%d)/Card removed(%d)\n", fgIsBusAccessFailed, kalIsCardRemoved(prAdapter->prGlueInfo))); + } + 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; + DBGLOG(INIT, ERROR, ("No RX response\n")); + } + 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; + DBGLOG(INIT, ERROR, ("EVENT-ID Mismatch: %d\n", prInitHifRxHeader->rInitWifiEvent.ucEID)); + } + else if(prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, ("SEQ-NUM Mismatch: %d (expected: %d)\n", prInitHifRxHeader->rInitWifiEvent.ucSeqNum, ucCmdSeqNum)); + } + else { + prEventPendingError = (P_INIT_EVENT_PENDING_ERROR) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); + if(prEventPendingError->ucStatus != 0) { // 0 for download success + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, ("ERROR CODE: %d\n", prEventCmdResult->ucStatus)); + } + 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) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, ("Bus error(%d)/Card removed(%d)\n", fgIsBusAccessFailed, kalIsCardRemoved(prAdapter->prGlueInfo))); + } + else if(nicRxWaitResponse(prAdapter, + 0, + aucBuffer, + sizeof(INIT_HIF_RX_HEADER_T) + sizeof(INIT_EVENT_CMD_RESULT), + &u4RxPktLength) != WLAN_STATUS_SUCCESS) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, ("No RX response\n")); + } + else { + prInitHifRxHeader = (P_INIT_HIF_RX_HEADER_T) aucBuffer; + + // EID / SeqNum check + if(prInitHifRxHeader->rInitWifiEvent.ucEID != INIT_EVENT_ID_CMD_RESULT) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, ("EVENT-ID Mismatch: %d\n", prInitHifRxHeader->rInitWifiEvent.ucEID)); + } + else if(prInitHifRxHeader->rInitWifiEvent.ucSeqNum != ucCmdSeqNum) { + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, ("SEQ-NUM Mismatch: %d\n", prInitHifRxHeader->rInitWifiEvent.ucSeqNum)); + } + else { + prEventCmdResult = (P_INIT_EVENT_CMD_RESULT) (prInitHifRxHeader->rInitWifiEvent.aucBuffer); + if(prEventCmdResult->ucStatus != 0) { // 0 for download success + u4Status = WLAN_STATUS_FAILURE; + DBGLOG(INIT, ERROR, ("ERROR CODE: %d\n", prEventCmdResult->ucStatus)); + } + 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, 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) == 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; + } + else { + 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 +*/ +/*----------------------------------------------------------------------------*/ +UINT_32 wlanCRC32( + PUINT_8 buf, + UINT_32 len) +{ + UINT_32 i, crc32 = 0xFFFFFFFF; + 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 }; + + 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: + nicRxProcessPktWithoutReorder(prAdapter, prSwRfb); + break; + + case RX_PKT_DESTINATION_FORWARD: + nicRxProcessForwardPkt(prAdapter, prSwRfb); + break; + + case RX_PKT_DESTINATION_HOST_WITH_FORWARD: + nicRxProcessGOBroadcastPkt(prAdapter, prSwRfb); + break; + + case RX_PKT_DESTINATION_NULL: + nicRxReturnRFB(prAdapter, prSwRfb); + break; + + default: + break; + } + +#if CFG_HIF_RX_STARVATION_WARNING + prRxCtrl->u4DequeuedCnt++; +#endif + 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); + + for (i = 0; i < u4NumOfElem; i++) { + if (apfnOidHandlerWOTimeoutCheck[i] == pfnOidHandler) { + return FALSE; + } + } + + // set timer if need timeout check + cnmTimerStartTimer(prAdapter, + &(prAdapter->rOidTimeoutTimer), + 1000); + + 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 set up the MCUSYS's OSC stable time +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return none +*/ +/*----------------------------------------------------------------------------*/ + +#if CFG_SUPPORT_OSC_SETTING && defined(MT5931) +WLAN_STATUS +wlanSetMcuOscStableTime ( + IN P_ADAPTER_T prAdapter, + IN UINT_16 u2OscStableTime + ) +{ + UINT_8 ucCmdSeqNum = 0; + P_CMD_INFO_T prCmdInfo = NULL; + P_WIFI_CMD_T prWifiCmd = NULL; + P_CMD_MCU_LP_PARAM_T prMcuSetOscCmd = NULL; + WLAN_STATUS status = WLAN_STATUS_SUCCESS; + + ASSERT(prAdapter); + + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, + CMD_HDR_SIZE + sizeof(CMD_MCU_LP_PARAM_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_MCU_LP_PARAM_T cmd pkt + prCmdInfo->eCmdType = COMMAND_TYPE_GENERAL_IOCTL; + prCmdInfo->u2InfoBufLen = CMD_HDR_SIZE + sizeof(CMD_MCU_LP_PARAM_T); + prCmdInfo->pfCmdDoneHandler = NULL; + prCmdInfo->pfCmdTimeoutHandler = NULL; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->ucCID = CMD_ID_SET_OSC; + prCmdInfo->fgSetQuery = TRUE; + prCmdInfo->fgNeedResp = FALSE; + prCmdInfo->fgDriverDomainMCR = FALSE; + prCmdInfo->ucCmdSeqNum = ucCmdSeqNum; + prCmdInfo->u4SetInfoLen = sizeof(CMD_MCU_LP_PARAM_T); + + // 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_MCU_LP_PARAM_T + prMcuSetOscCmd = (P_CMD_MCU_LP_PARAM_T)(prWifiCmd->aucBuffer); + prMcuSetOscCmd->u2OscStableTime = u2OscStableTime; + + status = wlanSendCommand(prAdapter, prCmdInfo); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + return status; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + UINT_8 ucCmdSeqNum; + P_CMD_INFO_T prCmdInfo; + P_WIFI_CMD_T prWifiCmd; + P_CMD_BASIC_CONFIG prCmdBasicConfig; + UINT_32 u4SysTime; + + 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) { + return WLAN_STATUS_SUCCESS; + } + else { + // dynamic generate + u4SysTime = (UINT_32) kalGetTimeTick(); + + rMacAddr[0] = 0x00; + rMacAddr[1] = 0x08; + rMacAddr[2] = 0x22; + + kalMemCopy(&rMacAddr[3], &u4SysTime, 3); + } + } + + 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 + + if(wlanSendCommand(prAdapter, prCmdInfo) == WLAN_STATUS_RESOURCES) { + prCmdInfo->pfCmdDoneHandler = nicCmdEventQueryAddress; + kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T)prCmdInfo); + + return WLAN_STATUS_PENDING; + } + else { + 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; + + ASSERT(prAdapter); + ASSERT(prPacket); + + if (kalQoSFrameClassifierAndPacketInfo(prAdapter->prGlueInfo, + prPacket, + &ucPriorityParam, + &u4PacketLen, + aucEthDestAddr, + &fgIs1x, + &fgIsPAL, + &ucNetworkType) == TRUE) { + if(fgIs1x == FALSE) { + return FALSE; + } + else { + KAL_SPIN_LOCK_DECLARATION(); + 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); + + DBGLOG(RSN, INFO, ("T1X len=%d\n", u4PacketLen)); + + 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; +#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; + + kalEnqueueCommand(prAdapter->prGlueInfo, (P_QUE_ENTRY_T)prCmdInfo); + + return TRUE; + } + else { + ASSERT(0); + return FALSE; + } + } + } + else { + 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) { + P_STA_RECORD_T prSta = cnmGetStaRecByIndex(prAdapter, prCmdInfo->ucStaRecIndex); + if (prSta) { + kalMsleep(10); + secFsmEventEapolTxDone(prAdapter, prSta, TX_RESULT_SUCCESS); + } + } + + kalSecurityFrameSendComplete(prAdapter->prGlueInfo, + prCmdInfo->prPacket, + WLAN_STATUS_SUCCESS); +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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); + + 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 + 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; + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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 scanning result + 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 - + (((UINT_32)pucIEPtr) + u4IELength - ((UINT_32)(&(prAdapter->rWlanInfo.aucScanIEBuf[0])))); + + kalMemCopy(pucIEPtr, + (PUINT_8)(((UINT_32)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)((UINT_32)(prAdapter->rWlanInfo.apucScanResultIEs[j]) - u4IELength); + } + } + } + } + + i++; + } + + return; +} + + +#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 + return; +} + +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); + + return; +} +#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; + + wlanSendCommand(prAdapter, prCmdInfo); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + if(nicRxWaitResponse(prAdapter, + 1, + aucBuffer, + sizeof(WIFI_EVENT_T) + sizeof(EVENT_BASIC_CONFIG), + &u4RxPktLength) != WLAN_STATUS_SUCCESS) { + return WLAN_STATUS_FAILURE; + } + + // header checking .. + prHifRxHdr = (P_HIF_RX_HEADER_T)aucBuffer; + if(prHifRxHdr->u2PacketType != 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_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; + + wlanSendCommand(prAdapter, prCmdInfo); + cmdBufFreeCmdInfo(prAdapter, prCmdInfo); + + 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_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; + + return WLAN_STATUS_SUCCESS; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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))); + } + } + + /* 3. Check if needs to support 5GHz */ + if(prRegInfo->ucEnable5GBand) { + // check if it is disabled by hardware + if(prAdapter->fgIsHw5GBandDisabled + || prRegInfo->ucSupport5GBand == 0) { + prAdapter->fgEnable5GBand = FALSE; + } + else { + prAdapter->fgEnable5GBand = TRUE; + } + } + else { + prAdapter->fgEnable5GBand = FALSE; + } + + /* 4. Send EFUSE data */ + 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)); + +#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); + + /* 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; + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_EDGE_TXPWR_LIMIT, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + sizeof(CMD_EDGE_TXPWR_LIMIT_T), + (PUINT_8)&rCmdEdgeTxPwrLimit, + 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); + + 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++) { + 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; + + 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; + } + else { + prMsduInfo->eSrc = TX_PACKET_OS; + + if(nicTxFillMsduInfo(prAdapter, + prMsduInfo, + prNativePacket) == FALSE) { // packet is not extractable + kalSendComplete(prAdapter->prGlueInfo, + prNativePacket, + WLAN_STATUS_INVALID_PACKET); + + nicTxReturnMsduInfo(prAdapter, prMsduInfo); + + return WLAN_STATUS_INVALID_PACKET; + } + else { + // 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 packet by txDequeuTxPackets() + 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 packets + nicTxMsduInfoList(prAdapter, prMsduInfo); + + // <4> update TC by txAdjustTcQuotas() + nicTxAdjustTcq(prAdapter); + } + else { + wlanProcessQueuedMsduInfo(prAdapter, prMsduInfo); + } + } + +#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); + + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + + /* Reset sleepy state */ + 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); + + 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; + + 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; + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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); + } + + return; +} + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_oid.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_oid.c new file mode 100755 index 000000000000..8d300b6cc355 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/common/wlan_oid.c @@ -0,0 +1,10556 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/common/wlan_oid.c#2 $ +*/ + +/*! \file wlanoid.c + \brief This file contains the WLAN OID processing routines of Windows driver for + MediaTek Inc. 802.11 Wireless LAN Adapters. +*/ + +/****************************************************************************** +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************* +*/ + +/****************************************************************************** +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************* +*/ + +/* +** $Log: wlan_oid.c $ + * + * 01 19 2012 yuche.tsai + * NULL + * Fix RX filter issue for P2P network. + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 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 06 2011 cp.wu + * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path + * sync. for connect-by-bssid control path implementations. + * + * 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 10 2011 tsaiyuan.hsu + * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered + * add debug counters of ar and bb 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 avoid compiler error. + * + * 11 04 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 Xlog 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 + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 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 uapsd, online scan in sw control. + * + * 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 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 22 2011 george.huang + * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command + * link with supplicant commands + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 occured 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 availble 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 + * upate 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 occured + * + * 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 managment macro + * + * 05 25 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * correct BSSID_LIST oid when radio if turned off. + * + * 05 24 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) when acquiring LP-own, write for clr-own with lower frequency compared to read poll + * 2) correct address list parsing + * + * 05 24 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * disable wlanoidSetNetworkAddress() temporally. + * + * 05 22 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * some OIDs should be DRIVER_CORE instead of GLUE_EXTENSION + * + * 05 22 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) disable NETWORK_LAYER_ADDRESSES handling temporally. + * 2) finish statistics OIDs + * + * 05 22 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * change OID behavior to meet WHQL requirement. + * + * 05 20 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS + * 2) buffer statistics data for 2 seconds + * 3) use default value for adhoc parameters instead of 0 + * + * 05 19 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) do not take timeout mechanism for power mode oids + * 2) retrieve network type from connection status + * 3) after disassciation, set radio state to off + * 4) TCP option over IPv6 is supported + * + * 05 18 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * implement Wakeup-on-LAN except firmware integration part + * + * 05 17 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * correct wlanoidSet802dot11PowerSaveProfile implementation. + * + * 05 17 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) enable CMD/EVENT ver 0.9 definition. + * 2) abandon use of ENUM_MEDIA_STATE + * + * 05 17 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * correct OID_802_11_DISASSOCIATE handling. + * + * 05 17 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * 1) add timeout handler mechanism for pending command packets + * 2) add p2p add/removal key + * + * 05 14 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * Add dissassocation support for wpa supplicant + * + * 05 14 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * correct return value. + * + * 05 13 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * add NULL OID implementation for WOL-related OIDs. + * + * 05 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * for disassociation, still use parameter with current setting. + * + * 05 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * for disassociation, generate a WZC-compatible invalid SSID. + * + * 05 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * associate to illegal SSID when handling OID_802_11_DISASSOCIATE + * + * 04 27 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * reserve field of privacy filter and RTS threshold setting. + * + * 04 23 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * surpress compiler warning + * + * 04 23 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * . + * + * 04 22 2010 cp.wu + * [WPD00003830]add OID_802_11_PRIVACY_FILTER support + * enable RX filter OID + * + * 04 19 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * Add ioctl of power management + * + * 04 14 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * information buffer for query oid/ioctl is now buffered in prCmdInfo + * * instead of glue-layer variable to improve multiple oid/ioctl capability + * + * 04 13 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * add framework for BT-over-Wi-Fi support. + * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability + * * * * 2) command sequence number is now increased atomically + * * * * 3) private data could be hold and taken use for other purpose + * + * 04 12 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * correct OID_802_11_CONFIGURATION query for infrastructure mode. + * + * 04 09 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * 1) remove unused spin lock declaration + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * finish non-glue layer access to glue variables + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * rWlanInfo should be placed at adapter rather than glue due to most operations + * * are done in adapter layer. + * + * 04 07 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * (1)improve none-glue code portability + * (2) disable set Multicast address during atomic context + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * ePowerCtrl is not necessary as a glue variable. + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. + * + * 04 06 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * improve none-glue code portability + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved + * + * 04 01 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * . + * + * 03 31 2010 wh.su + * [WPD00003816][MT6620 Wi-Fi] Adding the security support + * modify the wapi related code for new driver's design. + * + * 03 30 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * statistics information OIDs are now handled by querying from firmware domain + * + * 03 28 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * improve glue code portability + * + * 03 26 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * indicate media stream mode after set is done + * + * 03 26 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * add a temporary flag for integration with CMD/EVENT v0.9. + * + * 03 25 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior. + * the frequency is used for adhoc connection only + * 2) update with SD1 v0.9 CMD/EVENT documentation + * + * 03 24 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * [WPD00003826] Initial import for Linux port + * initial import for Linux port + * + * 03 24 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * initial import for Linux port + * + * 03 24 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK + * + * + * 03 22 2010 cp.wu + * [WPD00003824][MT6620 Wi-Fi][New Feature] Add support of large scan list + * Implement feature needed by CR: WPD00003824: refining association command by pasting scanning result + * + * 03 19 2010 wh.su + * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test + * adding the check for pass WHQL test item. + * + * 03 19 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) add ACPI D0/D3 state switching support + * * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response + * +* 03 16 2010 wh.su + * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test + * fixed some whql pre-test fail case. + * + * 03 03 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * implement custom OID: EEPROM read/write access + * + * 03 03 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * implement OID_802_3_MULTICAST_LIST oid handling + * + * 03 02 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) the use of prPendingOid revised, all accessing are now protected by spin lock + * * 2) ensure wlanReleasePendingOid will clear all command queues + * + * 02 25 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * send CMD_ID_INFRASTRUCTURE when handling OID_802_11_INFRASTRUCTURE_MODE set. + * + * 02 24 2010 wh.su + * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test + * Don't needed to check the auth mode, WHQL testing not specific at auth wpa2. + * + * 02 23 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * do not check SSID validity anymore. + * + * 02 23 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * add checksum offloading support. + * + * 02 09 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address + * * 2. follow MSDN defined behavior when associates to another AP + * * 3. for firmware download, packet size could be up to 2048 bytes + * + * 02 09 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * move ucCmdSeqNum as instance variable + * + * 02 04 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * when OID_CUSTOM_OID_INTERFACE_VERSION is queried, do modify connection states + * + * 01 27 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) implement timeout mechanism when OID is pending for longer than 1 second + * * 2) allow OID_802_11_CONFIGURATION to be executed when RF test mode is turned on + * + * 01 27 2010 wh.su + * [WPD00003816][MT6620 Wi-Fi] Adding the security support + * . + * + * 01 27 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1. eliminate improper variable in rHifInfo + * * 2. block TX/ordinary OID when RF test mode is engaged + * * 3. wait until firmware finish operation when entering into and leaving from RF test mode + * * 4. correct some HAL implementation + * + * 01 22 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * implement following 802.11 OIDs: + * OID_802_11_RSSI, + * OID_802_11_RSSI_TRIGGER, + * OID_802_11_STATISTICS, + * OID_802_11_DISASSOCIATE, + * OID_802_11_POWER_MODE + * + * 01 21 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * implement OID_802_11_MEDIA_STREAM_MODE + * + * 01 21 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * implement OID_802_11_SUPPORTED_RATES / OID_802_11_DESIRED_RATES + * + * 01 21 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * do not fill ucJoinOnly currently + * + * 01 14 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * enable to connect to ad-hoc network + * + * 01 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * .implement Set/Query BeaconInterval/AtimWindow + * + * 01 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * .Set/Get AT Info is not blocked even when driver is not in fg test mode + * + * 12 30 2009 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) According to CMD/EVENT documentation v0.8, + * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used, + * and result is retrieved by get ATInfo instead + * 2) add 4 counter for recording aggregation statistics + * + * 12 28 2009 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * eliminate redundant variables for connection_state +** \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-12-16 22:13:36 GMT mtk02752 +** change hard-coded MAC address to match with FW (temporally) +** \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-12-10 16:49:50 GMT mtk02752 +** code clean +** \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-12-08 17:38:49 GMT mtk02752 +** + add OID for RF test +** * MCR RD/WR are modified to match with cmd/event definition +** \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-12-08 11:32:20 GMT mtk02752 +** add skeleton for RF test implementation +** \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-12-03 16:43:24 GMT mtk01461 +** Modify query SCAN list oid by adding prEventScanResult +** +** \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-03 16:39:27 GMT mtk01461 +** Sync CMD data structure in set ssid oid +** \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-03 16:28:22 GMT mtk01461 +** Add invalid check of set SSID oid and fix query scan list oid +** \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-30 17:33:08 GMT mtk02752 +** implement wlanoidSetInfrastructureMode/wlanoidQueryInfrastructureMode +** \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-30 10:53:49 GMT mtk02752 +** 1st DW of WIFI_CMD_T is shared with HIF_TX_HEADER_T +** \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-30 09:22:48 GMT mtk02752 +** correct wifi cmd length mismatch +** \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-25 21:34:33 GMT mtk02752 +** sync EVENT_SCAN_RESULT_T with firmware +** \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-25 21:03:27 GMT mtk02752 +** implement wlanoidQueryBssidList() +** \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-25 18:17:17 GMT mtk02752 +** refine GL_WLAN_INFO_T for buffering scan result +** \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-11-23 20:28:51 GMT mtk02752 +** some OID will be set to WLAN_STATUS_PENDING until it is sent via wlanSendCommand() +** \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-11-23 17:56:36 GMT mtk02752 +** implement wlanoidSetBssidListScan(), wlanoidSetBssid() and wlanoidSetSsid() +** +** \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-11-13 17:20:53 GMT mtk02752 +** add Set BSSID/SSID path but disabled temporally due to FW is not ready yet +** \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-11-13 12:28:58 GMT mtk02752 +** add wlanoidSetBssidListScan -> cmd_info path +** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-11-09 22:48:07 GMT mtk01084 +** modify test cases entry +** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-04 14:10:58 GMT mtk01084 +** add new test interfaces +** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-10-30 18:17:10 GMT mtk01084 +** fix compiler warning +** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:46:26 GMT mtk01084 +** add test functions +** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:07:56 GMT mtk01084 +** include new file +** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:29 GMT mtk01084 +** modify for new HW architecture +** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-10-02 13:48:49 GMT mtk01725 +** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-09-09 17:26:04 GMT mtk01084 +** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-21 12:09:50 GMT mtk01461 +** Update for MCR Write OID +** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-21 09:35:18 GMT mtk01461 +** Update wlanoidQueryMcrRead() for composing CMD_INFO_T +** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-04-17 18:09:51 GMT mtk01426 +** Remove kalIndicateStatusAndComplete() in wlanoidQueryOidInterfaceVersion() +** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-04-14 15:51:50 GMT mtk01426 +** Add MCR read/write support +** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-19 18:32:40 GMT mtk01084 +** update for basic power management functions +** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:06:31 GMT mtk01426 +** Init for develop +** +*/ + +/****************************************************************************** +* C O M P I L E R F L A G S +******************************************************************************* +*/ + +/****************************************************************************** +* E X T E R N A L R E F E R E N C E S +******************************************************************************* +*/ +#include "precomp.h" +#include "mgmt/rsn.h" + +#include + +/****************************************************************************** +* C O N S T A N T S +******************************************************************************* +*/ +#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) + +/****************************************************************************** +* D A T A T Y P E S +******************************************************************************* +*/ + +/****************************************************************************** +* P U B L I C D A T A +******************************************************************************* +*/ +#if DBG +extern UINT_8 aucDebugModule[DBG_MODULE_NUM]; +extern UINT_32 u4DebugModule; +UINT_32 u4DebugModuleTemp; +#endif /* DBG */ + +/****************************************************************************** +* 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 +******************************************************************************* +*/ +extern int sprintf(char * buf, const char * fmt, ...); + +/****************************************************************************** +* 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(REQ, TRACE, ("NDIS supported network type list: %ld\n", + prSupported->NumberOfItems)); + DBGLOG_MEM8(REQ, INFO, 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(REQ, 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(REQ, + 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(REQ, INFO, ("Not support network type: %d\n", eNewNetworkType)); + rStatus = WLAN_STATUS_NOT_SUPPORTED; + break; + + default: + DBGLOG(REQ, 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(REQ, 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 + ) +{ +#if (CFG_NVRAM_EXISTENCE_CHECK == 1) || (CFG_SW_NVRAM_VERSION_CHECK == 1) + const UINT_8 aucZeroMacAddr[] = NULL_MAC_ADDR; + BOOLEAN fgIsConfExist = TRUE; + P_REG_INFO_T prRegInfo; +#endif + + 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(REQ, 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 (CFG_NVRAM_EXISTENCE_CHECK == 1) + if(kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) { + fgIsConfExist = FALSE; + u4BssidListExLen += OFFSET_OF(PARAM_BSSID_EX_T, aucIEs); + } +#endif + +#if (CFG_SW_NVRAM_VERSION_CHECK == 1) + prRegInfo = kalGetConfiguration(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 + || (prAdapter->fgIsEmbbededMacAddrValid == FALSE && + (IS_BMCAST_MAC_ADDR(prRegInfo->aucMacAddr) + || EQUAL_MAC_ADDR(aucZeroMacAddr, prRegInfo->aucMacAddr))) + || prRegInfo->ucTxPwrValid == 0)) { + u4BssidListExLen += OFFSET_OF(PARAM_BSSID_EX_T, aucIEs); + } +#endif + + 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++; + } + } + +#if (CFG_NVRAM_EXISTENCE_CHECK == 1) + #define NVRAM_ERR_MSG "NVRAM WARNING: Err = 0x01" + if(kalIsConfigurationExist(prAdapter->prGlueInfo) == FALSE) { + prBssidEx = (P_PARAM_BSSID_EX_T)cp; + + /* generate fake result as error message */ + i = prAdapter->rWlanInfo.u4ScanResultNum; + + // zero + kalMemZero(prBssidEx, OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); + + // then fill buffer + COPY_MAC_ADDR(prBssidEx->arMacAddress, aucZeroMacAddr); + COPY_SSID(prBssidEx->rSsid.aucSsid, + prBssidEx->rSsid.u4SsidLen, + NVRAM_ERR_MSG, + strlen(NVRAM_ERR_MSG)); + prBssidEx->u4Privacy = 0; + prBssidEx->rRssi = 0; + prBssidEx->eNetworkTypeInUse = PARAM_NETWORK_TYPE_FH; + prBssidEx->rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); + prBssidEx->rConfiguration.u4BeaconPeriod = 100; + prBssidEx->rConfiguration.u4ATIMWindow = 1; + prBssidEx->rConfiguration.u4DSConfig = 2412000; + prBssidEx->rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); + prBssidEx->eOpMode = BSS_TYPE_INFRASTRUCTURE; + prBssidEx->u4IELength = 0; + + /* move to next entry */ + prBssidEx->u4Length = OFFSET_OF(PARAM_BSSID_EX_T, aucIEs); + cp += prBssidEx->u4Length; + prList->u4NumberOfItems++; + } +#endif + +#if (CFG_SW_NVRAM_VERSION_CHECK == 1) + #define VER_ERR_MSG "NVRAM WARNING: Err = 0x%02X" + if(fgIsConfExist == TRUE) { + UINT_32 u4ErrCode = 0; + + 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(u4ErrCode != 0) { + UINT_8 aucErrMsg[32]; + prBssidEx = (P_PARAM_BSSID_EX_T)cp; + + // zero + kalMemZero(prBssidEx, OFFSET_OF(PARAM_BSSID_EX_T, aucIEs)); + + // then fill buffer + COPY_MAC_ADDR(prBssidEx->arMacAddress, aucZeroMacAddr); + + sprintf(aucErrMsg, VER_ERR_MSG, (unsigned int)u4ErrCode); + COPY_SSID(prBssidEx->rSsid.aucSsid, + prBssidEx->rSsid.u4SsidLen, + aucErrMsg, + strlen(aucErrMsg)); + + prBssidEx->u4Privacy = 0; + prBssidEx->rRssi = 0; + prBssidEx->eNetworkTypeInUse = PARAM_NETWORK_TYPE_FH; + prBssidEx->rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T); + prBssidEx->rConfiguration.u4BeaconPeriod = 100; + prBssidEx->rConfiguration.u4ATIMWindow = 1; + prBssidEx->rConfiguration.u4DSConfig = 2412000; + prBssidEx->rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T); + prBssidEx->eOpMode = BSS_TYPE_INFRASTRUCTURE; + prBssidEx->u4IELength = 0; + + /* move to next entry */ + prBssidEx->u4Length = OFFSET_OF(PARAM_BSSID_EX_T, aucIEs); + cp += prBssidEx->u4Length; + prList->u4NumberOfItems++; + } + } +#endif + + 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; + + DEBUGFUNC("wlanoidSetBssidListScan()"); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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(REQ, WARN, ("Return from BSSID list scan! (radio off). ACPI=D%d, Radio=%d\n", + prAdapter->rAcpiState, prAdapter->fgIsRadioOff)); + return WLAN_STATUS_SUCCESS; + } + + 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); + } + } + } + else +#endif + { + if(prAdapter->fgEnOnlineScan == TRUE) { + aisFsmScanRequest(prAdapter, prSsid); + } + else { + if(kalGetMediaStateIndicated(prAdapter->prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) { + aisFsmScanRequest(prAdapter, prSsid); + } + } + } + + return WLAN_STATUS_SUCCESS; +} /* wlanoidSetBssidListScan */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + + 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(REQ, 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); + } + else { + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + NULL, + 0); + } + } + + // 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 = DISCONNECT_REASON_CODE_NEW_CONNECTION; + + if (EQUAL_MAC_ADDR(prAdapter->rWifiVar.rConnSettings.aucBSSID, pAddr)) { + prAisAbortMsg->fgDelayIndication = TRUE; + } + else { + /* 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); + prAisAbortMsg->fgDelayIndication = FALSE; + } + + mboxSendMsg(prAdapter, + MBOX_ID_0, + (P_MSG_HDR_T) prAisAbortMsg, + MSG_SEND_METHOD_BUF); + + return WLAN_STATUS_SUCCESS; +} /* end of wlanoidSetBssid() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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(REQ, 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 { + 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; + + if (EQUAL_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, + prAdapter->rWifiVar.rConnSettings.ucSSIDLen, + pParamSsid->aucSsid, + pParamSsid->u4SsidLen)) { + prAisAbortMsg->fgDelayIndication = TRUE; + } + else { + /* Update the information to CONNECTION_SETTINGS_T */ + COPY_SSID(prAdapter->rWifiVar.rConnSettings.aucSSID, + prAdapter->rWifiVar.rConnSettings.ucSSIDLen, + pParamSsid->aucSsid, + (UINT_8)pParamSsid->u4SsidLen); + + 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(REQ, WARN, ("Invalid length %lu\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(REQ, 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(REQ, INFO, ("IBSS mode\n")); + break; + case NET_TYPE_INFRA: + DBGLOG(REQ, INFO, ("Infrastructure mode\n")); + break; + default: + DBGLOG(REQ, 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(REQ, 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(REQ, 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(REQ, 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(REQ, INFO, ("Current auth mode: Open\n")); + break; + + case AUTH_MODE_SHARED: + DBGLOG(REQ, INFO, ("Current auth mode: Shared\n")); + break; + + case AUTH_MODE_AUTO_SWITCH: + DBGLOG(REQ, INFO, ("Current auth mode: Auto-switch\n")); + break; + + case AUTH_MODE_WPA: + DBGLOG(REQ, INFO, ("Current auth mode: WPA\n")); + break; + + case AUTH_MODE_WPA_PSK: + DBGLOG(REQ, INFO, ("Current auth mode: WPA PSK\n")); + break; + + case AUTH_MODE_WPA_NONE: + DBGLOG(REQ, INFO, ("Current auth mode: WPA None\n")); + break; + + case AUTH_MODE_WPA2: + DBGLOG(REQ, INFO, ("Current auth mode: WPA2\n")); + break; + + case AUTH_MODE_WPA2_PSK: + DBGLOG(REQ, INFO, ("Current auth mode: WPA2 PSK\n")); + break; + + default: + DBGLOG(REQ, INFO, ("Current auth mode: %d\n", + *(P_ENUM_PARAM_AUTH_MODE_T)pvQueryBuffer)); + } +#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(REQ, 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(REQ, 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: + ; + } + + /* 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(REQ, INFO, ("Current privacy mode: open mode\n")); + break; + + case PRIVACY_FILTER_8021xWEP: + DBGLOG(REQ, INFO, ("Current privacy mode: filtering mode\n")); + break; + + default: + DBGLOG(REQ, 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(REQ, 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(REQ, 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(REQ, 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; + prAdapter->rWifiVar.rConnSettings.eEncStatus = ENUM_ENCRYPTION1_KEY_ABSENT;//ENUM_ENCRYPTION_DISABLED; + { + 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(INIT, 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(REQ, 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(REQ, 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(REQ, 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(REQ, 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(REQ, 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(REQ, 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(REQ, INFO, ("Set: Dump PARAM_KEY_INDEX content\n")); + DBGLOG(REQ, INFO, ("Index : 0x%08lx\n", u4KeyId)); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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(REQ, ERROR, ("Invalid WEP key index: 0x%08lx\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(REQ, ERROR, ("invalid WEP key ID %lu\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, + 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; + + DEBUGFUNC("wlanoidSetAddKey"); + DBGLOG(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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(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 */ + 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 */ + 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; + + /* Dump PARAM_KEY content. */ + DBGLOG(REQ, TRACE, ("Set: Dump PARAM_KEY content\n")); + DBGLOG(REQ, TRACE, ("Length : 0x%08lx\n", prNewKey->u4Length)); + DBGLOG(REQ, TRACE, ("Key Index : 0x%08lx\n", prNewKey->u4KeyIndex)); + DBGLOG(REQ, TRACE, ("Key Length: 0x%08lx\n", prNewKey->u4KeyLength)); + DBGLOG(REQ, TRACE, ("BSSID:\n")); + DBGLOG_MEM8(REQ, TRACE, prNewKey->arBSSID, sizeof(PARAM_MAC_ADDRESS)); + DBGLOG(REQ, TRACE, ("Key RSC:\n")); + DBGLOG_MEM8(REQ, TRACE, &prNewKey->rKeyRSC, sizeof(PARAM_KEY_RSC)); + DBGLOG(REQ, TRACE, ("Key Material:\n")); + DBGLOG_MEM8(REQ, 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 */ + } + + 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(INIT, ERROR, ("Allocate CMD_INFO_T ==> FAILED.\n")); + return WLAN_STATUS_FAILURE; + } + + // increase command sequence number + ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter); + DBGLOG(REQ, INFO, ("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 = 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 */ + + 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 (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; + } + } + 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 { + 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)); + } + prCmdKey->ucAlgorithmId = CIPHER_SUITE_TKIP; + } + } + + // insert into prCmdQueue + kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T)prCmdInfo); + + // wakeup txServiceThread later + GLUE_SET_EVENT(prGlueInfo); + + return WLAN_STATUS_PENDING; +} /* 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(REQ, 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(REQ, INFO, ("Set: Dump PARAM_REMOVE_KEY content\n")); + DBGLOG(REQ, INFO, ("Length : 0x%08lx\n", prRemovedKey->u4Length)); + DBGLOG(REQ, INFO, ("Key Index : 0x%08lx\n", prRemovedKey->u4KeyIndex)); + DBGLOG(REQ, INFO, ("BSSID:\n")); + DBGLOG_MEM8(REQ, INFO, 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(REQ, ERROR, ("invalid key index: 0x%08lx\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%08lx\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(INIT, 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; + } + else { + 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(REQ, ERROR, ("Unknown Encryption Status Setting:%d\n", + prAdapter->rWifiVar.rConnSettings.eEncStatus)); + } + +#if DBG + DBGLOG(REQ, 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(REQ, 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(REQ, 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; + } + + 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(REQ, TRACE, ("Test - Type %ld\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; + 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(REQ, INFO, ("Count %lu\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 "MACSTR" idx=%d PMKID value "MACSTR"\n", + MAC2STR(prAisSpecBssInfo->arPmkidCache[j].rBssidInfo.arBSSID),j, MAC2STR(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(REQ, WARN, ("Invalid length %ld\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(REQ, WARN, ("Invalid length %ld\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(REQ, WARN, ("Invalid length %ld\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(REQ, 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(REQ, WARN, ("Too short length %ld\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(REQ, WARN, ("Too short length %ld\n", u4QueryBufferLen)); + return WLAN_STATUS_BUFFER_TOO_SHORT; + } + + *(PARAM_RSSI *) pvQueryBuffer = prAdapter->rWlanInfo.rRssiTriggerValue; + DBGLOG(REQ, INFO, ("RSSI trigger: %ld 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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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 +wlanoidQueryStatistics ( + IN P_ADAPTER_T prAdapter, + IN PVOID pvQueryBuffer, + IN UINT_32 u4QueryBufferLen, + OUT PUINT_32 pu4QueryInfoLen + ) +{ + DEBUGFUNC("wlanoidQueryStatistics"); + DBGLOG(REQ, 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(REQ, 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(REQ, WARN, ("Too short length %ld\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; + } + else +#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(REQ, WARN, ("Invalid length %ld\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(REQ, WARN, ("Invalid length %ld\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(INIT, 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(INIT, 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) { + *(PUINT_32)pvQueryBuffer = 10000; // change to unit of 100bps + return WLAN_STATUS_SUCCESS; + } + 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_STRUC_T prMcrRdInfo; + CMD_ACCESS_REG rCmdAccessReg; + + DEBUGFUNC("wlanoidQueryMcrRead"); + DBGLOG(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + + *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUC_T); + + if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUC_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(INIT, TRACE, ("MCR Read: Offset = %#08lx, Data = %#08lx\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_STRUC_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(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_MCR_RW_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_MCR_RW_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prMcrWrInfo = (P_PARAM_CUSTOM_MCR_RW_STRUC_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(INIT, 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(INIT, 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(INIT, TRACE, ("MCR Write: Offset = %#08lx, Data = %#08lx\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_STRUC_T prSwCtrlInfo; + WLAN_STATUS rWlanStatus; + UINT_16 u2Id, u2SubId; + UINT_32 u4Data; + + CMD_SW_DBG_CTRL_T rCmdSwCtrl; + + DEBUGFUNC("wlanoidQuerySwCtrlRead"); + DBGLOG(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + + *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUC_T); + + if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUC_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_STRUC_T prSwCtrlInfo; + CMD_SW_DBG_CTRL_T rCmdSwCtrl; + WLAN_STATUS rWlanStatus; + UINT_16 u2Id, u2SubId; + UINT_32 u4Data; + + DEBUGFUNC("wlanoidSetSwCtrlWrite"); + DBGLOG(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_SW_CTRL_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_SW_CTRL_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUC_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; + } + + 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; + } + 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, INFO, ("set smt fixed rate: %d \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 + 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 + 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, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(CMD_ACCESS_REG), + (PUINT_8)&rCmdAccessReg, + pvSetBuffer, + 0 + ); + + // 4. Disable Roaming + rCmdSwCtrl.u4Id = 0x90000204; + rCmdSwCtrl.u4Data = 0x0; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(CMD_SW_DBG_CTRL_T), + (PUINT_8)&rCmdSwCtrl, + pvSetBuffer, + u4SetBufferLen + ); + + rCmdSwCtrl.u4Id = 0x90000200; + rCmdSwCtrl.u4Data = 0x820000; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(CMD_SW_DBG_CTRL_T), + (PUINT_8)&rCmdSwCtrl, + pvSetBuffer, + u4SetBufferLen + ); + + // 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, + FALSE); + } + + // 5. Disable Beacon Timeout Detection + prAdapter->fgDisBcnLostDetection = TRUE; + } + else if (u2SubId == 0x1235) { + + // 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, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(CMD_ACCESS_REG), + (PUINT_8)&rCmdAccessReg, + pvSetBuffer, + 0 + ); + + // 4. Enable Roaming + rCmdSwCtrl.u4Id = 0x90000204; + rCmdSwCtrl.u4Data = 0x1; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(CMD_SW_DBG_CTRL_T), + (PUINT_8)&rCmdSwCtrl, + pvSetBuffer, + u4SetBufferLen + ); + + rCmdSwCtrl.u4Id = 0x90000200; + rCmdSwCtrl.u4Data = 0x820000; + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SW_DBG_CTRL, + TRUE, + FALSE, + FALSE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(CMD_SW_DBG_CTRL_T), + (PUINT_8)&rCmdSwCtrl, + pvSetBuffer, + u4SetBufferLen + ); + + // 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, + FALSE); + } + + // 5. Enable Beacon Timeout Detection + prAdapter->fgDisBcnLostDetection = FALSE; + } +#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_STRUC_T prEepromRwInfo; + CMD_ACCESS_EEPROM rCmdAccessEeprom; + + DEBUGFUNC("wlanoidQueryEepromRead"); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + + *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUC_T); + + if (u4QueryBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUC_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_STRUC_T prEepromRwInfo; + CMD_ACCESS_EEPROM rCmdAccessEeprom; + + DEBUGFUNC("wlanoidSetEepromWrite"); + DBGLOG(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_EEPROM_RW_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prEepromRwInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUC_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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, LOUD, ("\n")); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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; + } + else +#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(REQ, WARN, ("Custom OID interface version: %#08lX\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(REQ, WARN, ("Invalid MC list length %ld\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 = 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; + + DEBUGFUNC("wlanoidSetCurrentPacketFilter"); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + if (u4SetBufferLen < sizeof(UINT_32)) { + *pu4SetInfoLen = sizeof(UINT_32); + return WLAN_STATUS_INVALID_LENGTH; + } + ASSERT(pvSetBuffer); + + /* Set the new packet filter. */ + u4NewPacketFilter = *(PUINT_32) pvSetBuffer; + + DBGLOG(REQ, INFO, ("New packet filter: %#08lx\n", u4NewPacketFilter)); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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(REQ, INFO, ("Enable promiscuous mode\n")); + } + else { + DBGLOG(REQ, INFO, ("Disable promiscuous mode\n")); + } + + if (u4NewPacketFilter & PARAM_PACKET_FILTER_ALL_MULTICAST) { + DBGLOG(REQ, INFO, ("Enable all-multicast mode\n")); + } + else if (u4NewPacketFilter & PARAM_PACKET_FILTER_MULTICAST) { + DBGLOG(REQ, INFO, ("Enable multicast\n")); + } + else { + DBGLOG(REQ, INFO, ("Disable multicast\n")); + } + + if (u4NewPacketFilter & PARAM_PACKET_FILTER_BROADCAST) { + DBGLOG(REQ, INFO, ("Enable Broadcast\n")); + } + else { + DBGLOG(REQ, INFO, ("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(REQ, INFO, ("Query Power State: D0\n")); + break; + case ParamDeviceStateD1: + DBGLOG(REQ, INFO, ("Query Power State: D1\n")); + break; + case ParamDeviceStateD2: + DBGLOG(REQ, INFO, ("Query Power State: D2\n")); + break; + case ParamDeviceStateD3: + DBGLOG(REQ, 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(REQ, INFO, ("Set Power State: D0\n")); + kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32)ParamDeviceStateD0); + fgRetValue = nicpmSetAcpiPowerD0(prAdapter); + break; + case ParamDeviceStateD1: + DBGLOG(REQ, INFO, ("Set Power State: D1\n")); + /* no break here */ + case ParamDeviceStateD2: + DBGLOG(REQ, INFO, ("Set Power State: D2\n")); + /* no break here */ + case ParamDeviceStateD3: + DBGLOG(REQ, 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(REQ, 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(REQ, 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(REQ, WARN, ("Invalid length %ld\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(REQ, 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) { + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + 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(REQ, WARN, ("Invalid length %ld\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(INIT, INFO, ("Set Wi-Fi PS mode to CAM (%d)\n", ePowerMode)); + break; + case Param_PowerModeMAX_PSP: + DBGLOG(INIT, INFO, ("Set Wi-Fi PS mode to MAX PS (%d)\n", ePowerMode)); + break; + case Param_PowerModeFast_PSP: + DBGLOG(INIT, INFO, ("Set Wi-Fi PS mode to FAST PS (%d)\n", ePowerMode)); + break; + default: + DBGLOG(INIT, 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(REQ, TRACE, ("Invalid Beacon Interval = %ld\n", *pu4BeaconInterval)); + return WLAN_STATUS_INVALID_DATA; + } + + prAdapter->rWlanInfo.u2BeaconPeriod = (UINT_16)*pu4BeaconInterval; + + DBGLOG(REQ, 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(INIT, 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; + + DEBUGFUNC("wlanoidSetNetworkAddress"); + DBGLOG(INIT, 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) ((UINT_32) prNetworkAddress + + (UINT_32) (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_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(REQ, INFO, ("u4IpAddressCount (%d)\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(REQ, INFO, ("prNetAddrIp->in_addr:%d:%d:%d:%d\n", pucBuf[0], pucBuf[1],pucBuf[2],pucBuf[3])); + } + + prNetworkAddress = (P_PARAM_NETWORK_ADDRESS) ((UINT_32) prNetworkAddress + + (UINT_32) (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, + FALSE, + 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; + } + + 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; + } + + 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_STRUC_T prRfATInfo; + WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidRftestQueryAutoTest"); + + ASSERT(prAdapter); + if (u4QueryBufferLen) { + ASSERT(pvQueryBuffer); + } + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUC_T); + + if (u4QueryBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUC_T)) { + DBGLOG(REQ, ERROR, ("Invalid data. QueryBufferLen: %ld.\n", + u4QueryBufferLen)); + return WLAN_STATUS_INVALID_LENGTH; + } + + prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUC_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_STRUC_T prRfATInfo; + WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; + + DEBUGFUNC("wlanoidRftestSetAutoTest"); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_MTK_WIFI_TEST_STRUC_T); + + if (u4SetBufferLen != sizeof(PARAM_MTK_WIFI_TEST_STRUC_T)) { + DBGLOG(REQ, ERROR, ("Invalid data. SetBufferLen: %ld.\n", + u4SetBufferLen)); + return WLAN_STATUS_INVALID_LENGTH; + } + + prRfATInfo = (P_PARAM_MTK_WIFI_TEST_STRUC_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(INIT, 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; + } + else { + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + sizeof(CMD_TEST_CTRL_T))); + + if (!prCmdInfo) { + DBGLOG(INIT, 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(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)); + DBGLOG(REQ, TRACE, ("Command ID = 0x%08X\n", 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(REQ, 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(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_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(REQ, LOUD, ("\r\n")); + + if (u4SetBufferLen < 20 /* From EID to Group cipher */) { + prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; + 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, TRACE, ("Not WAPI IE ?! u4SetBufferLen = %d\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 += 2; + 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 %ld\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(REQ, LOUD, ("\r\n")); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(pu4SetInfoLen); + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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(REQ, 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(REQ, TRACE, ("Set: Dump P_PARAM_WPI_KEY_T content\r\n")); + DBGLOG(REQ, TRACE, ("TYPE : %d\r\n", prNewKey->eKeyType)); + DBGLOG(REQ, TRACE, ("Direction : %d\r\n", prNewKey->eDirection)); + DBGLOG(REQ, TRACE, ("KeyID : %d\r\n", prNewKey->ucKeyID)); + DBGLOG(REQ, TRACE, ("AddressIndex:\r\n")); + DBGLOG_MEM8(REQ, TRACE, prNewKey->aucAddrIndex, 12); + prNewKey->u4LenWPIEK = 16; + + DBGLOG_MEM8(REQ, TRACE, (PUINT_8)prNewKey->aucWPIEK, (UINT_8)prNewKey->u4LenWPIEK); + prNewKey->u4LenWPICK = 16; + + DBGLOG(REQ, TRACE, ("CK Key(%d):\r\n", (UINT_8)prNewKey->u4LenWPICK)); + DBGLOG_MEM8(REQ, TRACE, (PUINT_8)prNewKey->aucWPICK, (UINT_8)prNewKey->u4LenWPICK); + DBGLOG(REQ, 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(REQ, TRACE, (PUINT_8)prNewKey->aucPN, 16); + + prGlueInfo = prAdapter->prGlueInfo; + + prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u4SetBufferLen)); + + if (!prCmdInfo) { + DBGLOG(INIT, 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(REQ, 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 %ld\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(REQ, 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(REQ, 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(REQ, 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(REQ, 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_STRUC_T prWmmPsTestInfo; + WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; + CMD_SET_WMM_PS_TEST_STRUC_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_STRUC_T); + + prWmmPsTestInfo = (P_PARAM_CUSTOM_WMM_PS_TEST_STRUC_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_STRUC_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_STRUC_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUC_T)NULL; + P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T)NULL; + + DEBUGFUNC("wlanoidQuerySLTStatus"); + DBGLOG(REQ, LOUD, ("\r\n")); + + ASSERT(prAdapter); + ASSERT(pu4QueryInfoLen); + + *pu4QueryInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUC_T); + + if (u4QueryBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvQueryBuffer); + + prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUC_T)pvQueryBuffer; + + prSltInfo = &(prAdapter->rWifiVar.rSltInfo); + + switch (prMtkSltInfo->rSltFuncIdx) { + case ENUM_MTK_SLT_FUNC_LP_SET: + { + P_PARAM_MTK_SLT_LP_TEST_STRUC_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUC_T)NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUC_T)); + + prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUC_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_STRUC_T prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUC_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(REQ, LOUD, ("\r\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_MTK_SLT_TEST_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_MTK_SLT_TEST_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prMtkSltInfo = (P_PARAM_MTK_SLT_TEST_STRUC_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_STRUC_T prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUC_T)NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_INITIAL_STRUC_T)); + + prMtkSltInit = (P_PARAM_MTK_SLT_INITIAL_STRUC_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; + } + else { + 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; + } + else { + P_PARAM_MTK_SLT_TR_TEST_STRUC_T prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUC_T)NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_TR_TEST_STRUC_T)); + + prStaRec = prSltInfo->prPseudoStaRec; + prTRSetting = (P_PARAM_MTK_SLT_TR_TEST_STRUC_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 */ + prStaRec->u2HtCapInfo |= HT_CAP_INFO_SUP_CHNL_WIDTH; /* It would controls RFBW capability in WTBL. */ + prStaRec->ucDesiredPhyTypeSet = PHY_TYPE_BIT_HT; /* This controls RF BW, RF BW would be 40 only if + * 1. PHY_TYPE_BIT_HT is TRUE. + * 2. SCO is SCA/SCB. + */ + + /* 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 { + if (prBssInfo->ucPrimaryChannel <5) { + prBssInfo->ucPrimaryChannel = 8; // For channel 1, testing L20 at channel 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 { + if (prBssInfo->ucPrimaryChannel > 10) { + prBssInfo->ucPrimaryChannel = 3; // For channel 11 / 14. testing U20 at channel 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_STRUC_T prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUC_T)NULL; + + ASSERT(prMtkSltInfo->u4FuncInfoLen == sizeof(PARAM_MTK_SLT_LP_TEST_STRUC_T)); + + prLpSetting = (P_PARAM_MTK_SLT_LP_TEST_STRUC_T)&prMtkSltInfo->unFuncInfoContent; + + if (prSltInfo->prPseudoBssDesc == NULL) { + /* Please initial SLT Mode first. */ + break; + } + else { + 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) { + fgStatus = kalCfgDataRead16(prAdapter->prGlueInfo, + prNvramRwInfo->ucEepromIndex << 1, /* change to byte offset */ + &u2Data); + + if(fgStatus) { + prNvramRwInfo->u2EepromData = u2Data; + DBGLOG(REQ, INFO, ("NVRAM Read: index=%#X, data=%#02X\r\n", + prNvramRwInfo->ucEepromIndex, u2Data)); + } + else{ + DBGLOG(REQ, 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(REQ, INFO, ("EEPROM size =%d\r\n", prNvramRwInfo->u2EepromData)); + } + + *pu4QueryInfoLen = sizeof(PARAM_CUSTOM_EEPROM_RW_STRUC_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(INIT, 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; + + fgStatus = kalCfgDataWrite16(prAdapter->prGlueInfo, + prNvramRwInfo->ucEepromIndex << 1, /* change to byte offset */ + prNvramRwInfo->u2EepromData + ); + + if(fgStatus == FALSE){ + DBGLOG(REQ, 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; + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + ASSERT(u4SetBufferLen == 2); + + *pu4SetInfoLen = 2; + + pucCountry = pvSetBuffer; + + prAdapter->rWifiVar.rConnSettings.u2CountryCode = + (((UINT_16) pucCountry[0]) << 8) | ((UINT_16) pucCountry[1]) ; + + prAdapter->prDomainInfo = NULL; /* Force to re-search country code */ + rlmDomainSendCmd(prAdapter, TRUE); + + 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_STRUC_T prNoaParam; + CMD_CUSTOM_NOA_PARAM_STRUC_T rCmdNoaParam; + + DEBUGFUNC("wlanoidSetNoaParam"); + DBGLOG(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_NOA_PARAM_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_NOA_PARAM_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUC_T)pvSetBuffer; + + kalMemZero(&rCmdNoaParam, sizeof(CMD_CUSTOM_NOA_PARAM_STRUC_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_STRUC_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_STRUC_T prOppPsParam; + CMD_CUSTOM_OPPPS_PARAM_STRUC_T rCmdOppPsParam; + + DEBUGFUNC("wlanoidSetOppPsParam"); + DBGLOG(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUC_T)) { + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvSetBuffer); + + prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUC_T)pvSetBuffer; + + kalMemZero(&rCmdOppPsParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUC_T)); + rCmdOppPsParam.u4CTwindowMs = prOppPsParam->u4CTwindowMs; + + return wlanSendSetQueryCmd(prAdapter, + CMD_ID_SET_OPPPS_PARAM, + TRUE, + FALSE, + TRUE, + nicCmdEventSetCommon, + nicOidCmdTimeoutCommon, + sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUC_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_STRUC_T prUapsdParam; + CMD_CUSTOM_UAPSD_PARAM_STRUC_T rCmdUapsdParam; + P_PM_PROFILE_SETUP_INFO_T prPmProfSetupInfo; + P_BSS_INFO_T prBssInfo; + + + DEBUGFUNC("wlanoidSetUApsdParam"); + DBGLOG(INIT, LOUD,("\n")); + + ASSERT(prAdapter); + ASSERT(pu4SetInfoLen); + + *pu4SetInfoLen = sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUC_T); + + if (u4SetBufferLen < sizeof(PARAM_CUSTOM_UAPSD_PARAM_STRUC_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_STRUC_T)pvSetBuffer; + + kalMemZero(&rCmdUapsdParam, sizeof(CMD_CUSTOM_OPPPS_PARAM_STRUC_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_STRUC_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 %ld\n", u4SetBufferLen)); + return WLAN_STATUS_INVALID_LENGTH; + } + + if (prAdapter->rAcpiState == ACPI_STATE_D3) { + DBGLOG(REQ, 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 + printk(KERN_INFO DRV_NAME "BCM BWCS CMD: BWCS CMD = %02x%02x%02x%02x\n", + prPtaIpc->u.aucBTPParams[0], prPtaIpc->u.aucBTPParams[1], prPtaIpc->u.aucBTPParams[2], prPtaIpc->u.aucBTPParams[3]); + + printk(KERN_INFO DRV_NAME "BCM BWCS CMD: aucBTPParams[0] = %02x, aucBTPParams[1] = %02x, aucBTPParams[2] = %02x, aucBTPParams[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(REQ, WARN, ("Invalid length %lu\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(REQ, WARN, ("Invalid length %lu\n", u4QueryBufferLen)); + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvQueryBuffer); + + prPtaInfo = &prAdapter->rPtaInfo; + pu4SingleAntenna = (PUINT_32)pvQueryBuffer; + + if(prPtaInfo->fgSingleAntenna) { + //printk(KERN_WARNING DRV_NAME"Q Single Ant = 1\r\n"); + *pu4SingleAntenna = 1; + } else { + //printk(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(REQ, 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) { + //printk(KERN_WARNING DRV_NAME"Set Single Ant = 0\r\n"); + prPtaInfo->fgSingleAntenna = FALSE; + } else { + //printk(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(REQ, WARN, ("Invalid length %lu\n", u4QueryBufferLen)); + return WLAN_STATUS_INVALID_LENGTH; + } + + ASSERT(pvQueryBuffer); + + prPtaInfo = &prAdapter->rPtaInfo; + pu4Pta = (PUINT_32)pvQueryBuffer; + + if(prPtaInfo->fgEnabled) { + //printk(KERN_WARNING DRV_NAME"PTA = 1\r\n"); + *pu4Pta = 1; + } else { + //printk(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(REQ, 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) { + //printk(KERN_WARNING DRV_NAME"Set Pta= 0\r\n"); + nicPtaSetFunc(prAdapter, FALSE); + } else { + //printk(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(REQ, LOUD, ("\r\n")); + + ASSERT(prAdapter); + ASSERT(pvSetBuffer); + +#if 0 + printk("c2GLegacyStaPwrOffset=%d\n", pTxPwr->c2GLegacyStaPwrOffset); + printk("c2GHotspotPwrOffset=%d\n", pTxPwr->c2GHotspotPwrOffset); + printk("c2GP2pPwrOffset=%d\n", pTxPwr->c2GP2pPwrOffset); + printk("c2GBowPwrOffset=%d\n", pTxPwr->c2GBowPwrOffset); + printk("c5GLegacyStaPwrOffset=%d\n", pTxPwr->c5GLegacyStaPwrOffset); + printk("c5GHotspotPwrOffset=%d\n", pTxPwr->c5GHotspotPwrOffset); + printk("c5GP2pPwrOffset=%d\n", pTxPwr->c5GP2pPwrOffset); + printk("c5GBowPwrOffset=%d\n", pTxPwr->c5GBowPwrOffset); + printk("ucConcurrencePolicy=%d\n", pTxPwr->ucConcurrencePolicy); + + for (i=0; i<14;i++) + printk("acTxPwrLimit2G[%d]=%d\n", i, pTxPwr->acTxPwrLimit2G[i]); + + for (i=0; i<4;i++) + printk("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; + +} + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/CFG_Wifi_File.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/CFG_Wifi_File.h new file mode 100755 index 000000000000..6b253ef4cf5e --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/CFG_Wifi_File.h @@ -0,0 +1,284 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: CFG_Wifi_File.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 */ +#if defined(MT6620) + INT_8 acReserved[3]; +#elif defined(MT5931) || 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; +} 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 aucTailReserved[256-8]; +} 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_STRUC_INSPECTING_ASSERT +#define DATA_STRUC_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. + */ +__KAL_INLINE__ VOID +nvramOffsetCheck ( + VOID + ) +{ + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion) == 256); + + DATA_STRUC_INSPECTING_ASSERT( + sizeof(WIFI_CFG_PARAM_STRUCT) == 512); + + DATA_STRUC_INSPECTING_ASSERT( + (OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) & 0x0001) == 0); + + DATA_STRUC_INSPECTING_ASSERT( + (OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo) & 0x0001) == 0); +} +#endif + +#endif /* _CFG_WIFI_FILE_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/config.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/config.h new file mode 100755 index 000000000000..5bc1eb89991f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/config.h @@ -0,0 +1,1410 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/config.h#3 $ +*/ + +/*! \file "config.h" + \brief This file includes the various configurable parameters for customers + + This file ncludes the configurable parameters except the paramters indicate the turning-on/off of some features +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: config.h $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 01 16 2012 terry.wu + * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork + * Remove CFG80211_DUMMY_CALLBACK temp config. + * + * 01 09 2012 terry.wu + * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork + * cfg80211 integration for p2p network. + * + * 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 19 2011 yuche.tsai + * NULL + * Add P2P RSSI Link Quality Query Support. (Default 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 21 2011 terry.wu + * [WCXRP00001049] [MT6620 Wi-Fi] [Driver/FW] Sync branch 2.1 to ALPS + * Sync branch 2.1 configuration. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 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. + * + * 06 29 2011 terry.wu + * NULL + * Add BoW 11n support. + * + * 06 27 2011 tsaiyuan.hsu + * [WCXRP00000816] [MT6620 Wi-Fi][Driver] add control to enable rx data dump or not + * add control to enable rx data dump by packet type. + * + * 06 01 2011 cm.chang + * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function + * Limit AIS channel same with BOW when BOW is active + * + * 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 + * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events[WCXRP00000653] [MT6620 Wi-Fi][Firmware][Wi-Fi Task] Workaround for E3 MCU gating issue by masking HIF_EINT and invoking cos_get_subsystem_enable + * 1. add header dependency + * 2. sync config.h with ALPS release + * + * 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 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 + * sync. whole-chip resetting mechanism to V2.0 branch. + * + * 04 11 2011 george.huang + * [WCXRP00000628] [MT6620 Wi-Fi][FW][Driver] Modify U-APSD setting to default OFF + * . + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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] Chnage 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 adress & 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 reponse 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 +******************************************************************************** +*/ + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +//2 Flags for OS capability + +#ifdef LINUX + #ifdef CONFIG_X86 + #define MTK_WCN_HIF_SDIO 0 + #else + #define MTK_WCN_HIF_SDIO 1 + #endif +#else + #define MTK_WCN_HIF_SDIO 0 +#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 + +#define CFG_SUPPORT_802_11D 1 /*!< 1(default): Enable 802.11d + 0: Disable */ + +#define CFG_SUPPORT_SPEC_MGMT 0 /* Spectrum Management (802.11h): TPC and DFS */ +#define CFG_SUPPORT_RRM 0 /* Radio Reasource Measurement (802.11k) */ +#define CFG_SUPPORT_QUIET 0 /* Quiet (802.11h) */ + + +#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 */ + +/*------------------------------------------------------------------------------ + * SLT Option + *------------------------------------------------------------------------------ + */ +#define CFG_SLT_SUPPORT 0 + + +#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 1 +#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: Suport 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 + +#elif defined(MT5931) + +#define CFG_MULTI_ECOVER_SUPPORT 0 + +#elif defined(MT6628) + +#define CFG_MULTI_ECOVER_SUPPORT 0 + +#endif + +#if (MTK_WCN_HIF_SDIO == 1) +#define CFG_CHIP_RESET_SUPPORT 1 +#else +#define CFG_CHIP_RESET_SUPPORT 0 +#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 + +/*------------------------------------------------------------------------------ + * 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 256 + +/*! 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 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 + +#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 */ + +/*------------------------------------------------------------------------------ + * 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 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 1 +#else + #define CFG_IST_LOOP_COUNT 1 +#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(MT6620) || defined(MT6628) + #define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION 0 + #define CFG_ENABLE_FW_DIVIDED_DOWNLOAD 1 +#else + #define CFG_ENABLE_FW_DOWNLOAD_AGGREGATION 0 + #define CFG_ENABLE_FW_DIVIDED_DOWNLOAD 0 +#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(MT5931) + #define CFG_FW_LOAD_ADDRESS 0xFF900000 + #define CFG_FW_START_ADDRESS 0x00000000 +#elif defined(MT6628) + #define CFG_FW_LOAD_ADDRESS 0x00060000 + #define CFG_FW_START_ADDRESS 0x00060000 +#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 + +/*------------------------------------------------------------------------------ + * 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 1 +#define CFG_SUPPORT_AAA 1 + + +#if (defined(MT5931) && defined(LINUX)) +#define CFG_SUPPORT_BCM 1 +#define CFG_SUPPORT_BCM_BWCS 1 +#define CFG_SUPPORT_BCM_BWCS_DEBUG 1 +#else +#define CFG_SUPPORT_BCM 0 +#define CFG_SUPPORT_BCM_BWCS 0 +#define CFG_SUPPORT_BCM_BWCS_DEBUG 0 +#endif + +#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 0 +#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 + +#if defined(MT5931) +#define CFG_SUPPORT_WHOLE_CHIP_RESET 1 /* for e3 chip only */ +#endif + +#define CFG_SUPPORT_P2P_RSSI_QUERY 0 + +/******************************************************************************* +* 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/mtk_wcn_combo/drv_wlan/wlan/include/debug.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/debug.h new file mode 100755 index 000000000000..9711aff5c528 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/debug.h @@ -0,0 +1,566 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: debug.h $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 12 16 2011 wh.su + * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG + * fixed the compiling error at Windows free build. + * + * 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 + * Add XLOG related code and define. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 catagory +** \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" +#if CFG_SUPPORT_XLOG +#include "linux/xlog.h" +#endif + +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_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 "%02x:%02x:%02x:%02x:%02x:%02x" + +/* Debug print argument for the MAC Address */ +#define MAC2STR(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 " = " MACSTR "\n", MAC2STR(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. + */ +#define LOG_FUNC_TIME kalPrint +#define LOG_FUNC kalPrint + +#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(__FUNCTION__) + #define DEBUGFUNC(_Func) + #else + #define DEBUGFUNC(_Func) static const char __FUNCTION__[] = _Func; + #endif + + /* The following macros are used for future debug message. */ + /* TODO(Kevin): We should remove INITLOG/ERRORLOG/WARNLOG macro sooner or later */ + #define INITLOG(_Fmt) \ + { \ + if (aucDebugModule[DBG_INIT_IDX] & DBG_CLASS_TRACE) { \ + LOG_FUNC("%s: ", __FUNCTION__); \ + LOG_FUNC _Fmt; \ + } \ + } + + #define ERRORLOG(_Fmt) \ + { \ + if (aucDebugModule[DBG_INIT_IDX] & DBG_CLASS_ERROR) { \ + LOG_FUNC("**Error[%s:%d]-", __FILE__, __LINE__); \ + LOG_FUNC _Fmt; \ + } \ + } + + #define WARNLOG(_Fmt) \ + { \ + if (aucDebugModule[DBG_INIT_IDX] & DBG_CLASS_WARN) { \ + LOG_FUNC("**Warning[%s:%d]-", __FILE__, __LINE__); \ + LOG_FUNC _Fmt; \ + } \ + } + + /*lint -save -e960 Multiple use of '#/##' */ + #define DBGLOG(_Module, _Class, _Fmt) \ + { \ + if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ + if (DBG_CLASS_##_Class == DBG_CLASS_ERROR) { \ + LOG_FUNC_TIME("**Error[%s:%d]-", __FILE__, __LINE__); \ + LOG_FUNC("%s: (" #_Module " " #_Class ") ", __FUNCTION__); \ + } \ + else if (DBG_CLASS_##_Class == DBG_CLASS_WARN) { \ + LOG_FUNC_TIME("**Warning[%s:%d]-", __FILE__, __LINE__); \ + LOG_FUNC("%s: (" #_Module " " #_Class ") ", __FUNCTION__); \ + } \ + else if (DBG_CLASS_##_Class == DBG_CLASS_EVENT) { \ + } \ + else { \ + LOG_FUNC_TIME("%s: (" #_Module " " #_Class ") ", __FUNCTION__); \ + } \ + LOG_FUNC _Fmt; \ + } \ + } + + #define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \ + { \ + if (aucDebugModule[DBG_##_Module##_IDX] & DBG_CLASS_##_Class) { \ + LOG_FUNC("%s: (" #_Module " " #_Class ")\n", __FUNCTION__); \ + 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", __FUNCTION__); \ + 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) + +#if CFG_SUPPORT_XLOG + #define DBGLOG(_Module, _Class, _Fmt) \ + { \ + _Module##_##_Class##_LOGFUNC _Fmt; \ + } + + #define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) \ + { \ + _Module##_##_Class##_LOGFUNC (__FUNCTION__);\ + _Module##_##_Class##_LOGDUMP8(_StartAddr, _Length); \ + } + +#else + #define DBGLOG(_Module, _Class, _Fmt) + #define DBGLOG_MEM8(_Module, _Class, _StartAddr, _Length) +#endif + #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) + #define ASSERT_REPORT(_exp, _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_STRUC_INSPECTING_ASSERT +#define DATA_STRUC_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 +******************************************************************************** +*/ +#if DBG +VOID +dumpMemory8 ( + IN PUINT_8 pucStartAddr, + IN UINT_32 u4Length + ); + +VOID +dumpMemory32 ( + IN PUINT_32 pu4StartAddr, + IN UINT_32 u4Length + ); +#elif CFG_SUPPORT_XLOG +VOID +dumpMemory8 ( + IN UINT_32 log_level, + IN PUINT_8 pucStartAddr, + IN UINT_32 u4Length + ); +#endif /* DBG */ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _DEBUG_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/link.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/link.h new file mode 100755 index 000000000000..f7973a22a387 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/link.h @@ -0,0 +1,458 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: link.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +******************************************************************************** +*/ +#define INVALID_LINK_POISON1 ((VOID *) 0x00100101) // May cause page fault & unalignment issue (data abort) +#define INVALID_LINK_POISON2 ((VOID *) 0x00100201) // Used to verify that nonbody uses non-initialized link entries. + + +/******************************************************************************* +* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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; + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +linkAdd ( + IN P_LINK_ENTRY_T prNew, + IN P_LINK_T prLink + ) +{ + __linkAdd(prNew, (P_LINK_ENTRY_T)prLink, prLink->prNext); + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +linkAddTail ( + IN P_LINK_ENTRY_T prNew, + IN P_LINK_T prLink + ) +{ + __linkAdd(prNew, prLink->prPrev, (P_LINK_ENTRY_T)prLink); + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +__linkDel ( + IN P_LINK_ENTRY_T prPrev, + IN P_LINK_ENTRY_T prNext + ) +{ + prNext->prPrev = prPrev; + prPrev->prNext = prNext; + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +linkDel ( + IN P_LINK_ENTRY_T prEntry + ) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + + LINK_ENTRY_INITIALIZE(prEntry); + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +linkMove ( + IN P_LINK_ENTRY_T prEntry, + IN P_LINK_T prLink + ) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + linkAdd(prEntry, prLink); + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +linkMoveTail ( + IN P_LINK_ENTRY_T prEntry, + IN P_LINK_T prLink + ) +{ + __linkDel(prEntry->prPrev, prEntry->prNext); + linkAddTail(prEntry, prLink); + + return; +} /* end of linkMoveTail() */ + +#endif /* _LINK_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/aa_fsm.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/aa_fsm.h new file mode 100755 index 000000000000..996f5fa3cf63 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/aa_fsm.h @@ -0,0 +1,295 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: aa_fsm.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/ais_fsm.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/ais_fsm.h new file mode 100755 index 000000000000..ef4c9d2f2a64 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/ais_fsm.h @@ -0,0 +1,719 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 backgroud 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_DISCONNECT_SEC 10 + +#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 2000 + +/******************************************************************************* +* 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_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_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_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; + + 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]; + + /* Pending Request List */ + LINK_T rPendingReqList; + +} 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 + ); + +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 + ); + +/*----------------------------------------------------------------------------*/ +/* 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, + UINT_32 u4Param + ); + +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 + ); + +/*----------------------------------------------------------------------------*/ +/* Disconnection Handling */ +/*----------------------------------------------------------------------------*/ +VOID +aisFsmDisconnect ( + IN P_ADAPTER_T prAdapter, + IN BOOLEAN fgDelayIndication + ); + + +/*----------------------------------------------------------------------------*/ +/* Event Handling */ +/*----------------------------------------------------------------------------*/ +VOID +aisBssBeaconTimeout ( + 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, + UINT_32 u4Param + ); + +VOID +aisFsmRunEventIbssAloneTimeOut ( + IN P_ADAPTER_T prAdapter, + UINT_32 u4Param + ); + +VOID +aisFsmRunEventJoinTimeout ( + IN P_ADAPTER_T prAdapter, + UINT_32 u4Param + ); + +/*----------------------------------------------------------------------------*/ +/* OID/IOCTL Handling */ +/*----------------------------------------------------------------------------*/ +VOID +aisFsmScanRequest ( + IN P_ADAPTER_T prAdapter, + IN P_PARAM_SSID_T prSsid + ); + +/*----------------------------------------------------------------------------*/ +/* 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 + ); + + +#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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/assoc.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/assoc.h new file mode 100755 index 000000000000..b269c71668d0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/assoc.h @@ -0,0 +1,191 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: assoc.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 */ +/*----------------------------------------------------------------------------*/ +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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/auth.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/auth.h new file mode 100755 index 000000000000..827120b73033 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/auth.h @@ -0,0 +1,219 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: auth.h $ + * + * 04 21 2011 terry.wu + * [WCXRP00000674] [MT6620 Wi-Fi][Driver] Refine AAA authSendAuthFrame + * Add network type parameter to authSendAuthFrame. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bow_fsm.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bow_fsm.h new file mode 100755 index 000000000000..05cc3edb5099 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bow_fsm.h @@ -0,0 +1,234 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bss.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bss.h new file mode 100755 index 000000000000..49e56742f9f8 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/bss.h @@ -0,0 +1,457 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: bss.h $ + * + * 01 15 2012 yuche.tsai + * NULL + * Fix wrong basic rate issue. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 19 2011 yuche.tsai + * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue + * Append P2P IE in assoc request if P2P is enabled. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + ); + + +/*link function to p2p module for txBcnIETable*/ +#if CFG_ENABLE_WIFI_DIRECT +UINT_32 +linkToP2pCalculateP2P_IELenForBeacon ( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN P_STA_RECORD_T prStaRec + ); + +VOID +linkToP2pGenerateP2P_IEForBeacon ( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ); + +UINT_32 +linkToP2pCalculateWSC_IELenForBeacon ( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN P_STA_RECORD_T prStaRec + ); + +VOID +linkToP2pGenerateP2P_IEForAssocReq ( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ); + +VOID +linkToP2pGenerateP2P_IEForAssocRsp ( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ); + + +UINT_32 +linkToP2pCalculateP2P_IELenForAssocReq ( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN P_STA_RECORD_T prStaRec + ); + +UINT_32 +linkToP2pCalculateP2P_IELenForAssocRsp ( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN P_STA_RECORD_T prStaRec + ); + +VOID +linkToP2pGenerateWSC_IEForBeacon( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ); + +UINT_32 +linkToP2pCalculateWSC_IELenForProbeRsp ( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN P_STA_RECORD_T prStaRec + ); + +VOID +linkToP2pGenerateWSC_IEForProbeRsp( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ); +#endif + +/* 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm.h new file mode 100755 index 000000000000..fa8f927c5f10 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm.h @@ -0,0 +1,362 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/cnm.h#1 $ +*/ + +/*! \file "cnm.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: cnm.h $ + * + * 06 23 2011 cp.wu + * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module + * follow-ups for frequency-shifted WAPI AP support + * + * 04 12 2011 cm.chang + * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency + * . + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + ); + +/******************************************************************************* +* 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. + */ +__KAL_INLINE__ VOID +cnmMsgDataTypeCheck ( + VOID + ) +{ + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,rMsgHdr) == 0); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,rMsgHdr) == + OFFSET_OF(MSG_CH_RECOVER_T,rMsgHdr)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,ucNetTypeIndex) == + OFFSET_OF(MSG_CH_RECOVER_T,ucNetTypeIndex)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,ucTokenID) == + OFFSET_OF(MSG_CH_RECOVER_T,ucTokenID)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,ucPrimaryChannel) == + OFFSET_OF(MSG_CH_RECOVER_T,ucPrimaryChannel)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,eRfSco) == + OFFSET_OF(MSG_CH_RECOVER_T,eRfSco)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,eRfBand) == + OFFSET_OF(MSG_CH_RECOVER_T,eRfBand)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSG_CH_GRANT_T,eReqType) == + OFFSET_OF(MSG_CH_RECOVER_T,eReqType)); + + return; +} +#endif /* _lint */ + +#endif /* _CNM_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_mem.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_mem.h new file mode 100755 index 000000000000..16554b40ceec --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_mem.h @@ -0,0 +1,1196 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/cnm_mem.h#2 $ +*/ + +/*! \file "cnm_mem.h" + \brief In this file we define the structure of the control unit of + packet buffer and MGT/MSG Memory Buffer. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: cnm_mem.h $ + * + * 01 17 2012 wh.su + * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting + * Adding the related code which support beacon can reflect the security setting open or WPA2-PSK, WPA-PSK not yet + * Adn support the indicate the assoc request ie at New STA CMD, needed kernel patch. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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; + + BOOL fg2nd1xSend; + BOOL fgKeyStored; + + UINT_8 aucStoredKey[64]; + + BOOL 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; + + +/* 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 choosen 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 Alogrithm 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. Chnage 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 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 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 requred 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 + ); + +/******************************************************************************* +* 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. + */ +__KAL_INLINE__ VOID +cnmMemDataTypeCheck ( + VOID + ) +{ +#if 0 + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,rLinkEntry) == 0); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,rLinkEntry) == OFFSET_OF(SW_RFB_T,rLinkEntry)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,pucBuffer) == OFFSET_OF(SW_RFB_T,pucBuffer)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,ucBufferSource) == + OFFSET_OF(SW_RFB_T,ucBufferSource)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,pucMacHeader) == + OFFSET_OF(SW_RFB_T,pucMacHeader)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,ucMacHeaderLength) == + OFFSET_OF(SW_RFB_T,ucMacHeaderLength)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,pucPayload) == + OFFSET_OF(SW_RFB_T,pucPayload)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,u2PayloadLength) == + OFFSET_OF(SW_RFB_T,u2PayloadLength)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,prStaRec) == + OFFSET_OF(SW_RFB_T,prStaRec)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,ucNetworkTypeIndex) == + OFFSET_OF(SW_RFB_T,ucNetworkTypeIndex)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,ucTID) == + OFFSET_OF(SW_RFB_T,ucTID)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,fgIs802_11Frame) == + OFFSET_OF(SW_RFB_T,fgIs802_11Frame)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,ucControlFlag) == + OFFSET_OF(SW_RFB_T,ucControlFlag)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,rArrivalTime) == + OFFSET_OF(SW_RFB_T,rArrivalTime)); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,ucTC) == + OFFSET_OF(SW_RFB_T,ucTC)); + +#if CFG_PROFILE_BUFFER_TRACING + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,eActivity[0]) == + OFFSET_OF(SW_RFB_T,eActivity[0])); + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,rActivityTime[0]) == + OFFSET_OF(SW_RFB_T,rActivityTime[0])); +#endif + +#if DBG && CFG_BUFFER_FREE_CHK + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(MSDU_INFO_T,fgBufferInSource) == + OFFSET_OF(SW_RFB_T,fgBufferInSource)); +#endif + + + DATA_STRUC_INSPECTING_ASSERT( + OFFSET_OF(STA_RECORD_T,rLinkEntry) == 0); + + return; +#endif +} +#endif /* _lint */ + +#endif /* _CNM_MEM_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_scan.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_scan.h new file mode 100755 index 000000000000..a66376cc22bf --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_scan.h @@ -0,0 +1,250 @@ +/* +** $Id: @(#) +*/ + +/*! \file "cnm_scan.h" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: cnm_scan.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 32 + +/******************************************************************************* +* 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_timer.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_timer.h new file mode 100755 index 000000000000..58a897aaaba6 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/cnm_timer.h @@ -0,0 +1,318 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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 + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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, UINT_32); + +typedef struct _TIMER_T { + LINK_ENTRY_T rLinkEntry; + OS_SYSTIME rExpiredSysTime; + UINT_16 u2Minutes; + UINT_16 u2Reserved; + UINT_32 u4Data; + 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), (UINT_32)(_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 UINT_32 u4Data + ); + +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 +******************************************************************************** +*/ +__KAL_INLINE__ +INT_32 +timerPendingTimer ( + IN P_TIMER_T prTimer + ) +{ + ASSERT(prTimer); + + return prTimer->rLinkEntry.prNext != NULL; +} + +#endif /* _CNM_TIMER_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/hem_mbox.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/hem_mbox.h new file mode 100755 index 000000000000..c9636363385b --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/hem_mbox.h @@ -0,0 +1,486 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/hem_mbox.h#3 $ +*/ + +/*! \file hem_mbox.h + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: hem_mbox.h $ + * + * 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. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 08 10 2011 yuche.tsai + * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. + * Add infitation support. + * + * 06 23 2011 cp.wu + * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module + * follow-ups for frequency-shifted WAPI AP support + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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_DISCOVERY_ABORT, /* Start device discovery abort. */ + MID_MNY_P2P_CONNECTION_REQ, /* Connection request. */ + MID_MNY_P2P_CONNECTION_ABORT, /* Abort connection request, P2P FSM return to IDLE. */ + MID_MNY_P2P_CONNECTION_TRIGGER, /* Only if connection request is valid. Trigger P2P FSM to connection target AP. */ + MID_MNY_P2P_CONNECTION_PAUSE, /* Disconnect from target AP, connection is not complete yet. */ + MID_MNY_P2P_PROVISION_COMPLETE, /* Provisioning complete. */ + MID_MNY_P2P_INVITATION_REQ, + MID_MNY_P2P_INVITATION_ABORT, + MID_MNY_P2P_BEACON_UPDATE, + MID_MNY_P2P_BEACON_DEL, + 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, +#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 */ + + 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; + + + +/* 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/mib.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/mib.h new file mode 100755 index 000000000000..a669eb548f8b --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/mib.h @@ -0,0 +1,201 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: mib.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/privacy.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/privacy.h new file mode 100755 index 000000000000..f8dce21b67ea --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/privacy.h @@ -0,0 +1,332 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/privacy.h#1 $ +*/ + +/*! \file privacy.h + \brief This file contains the function declaration for privacy.c. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: privacy.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + ); + +BOOL +secCheckClassError( + IN P_ADAPTER_T prAdapter, + IN P_SW_RFB_T prSwRfb, + IN P_STA_RECORD_T prStaRec + ); + +BOOL +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 + ); + +BOOL +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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rate.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rate.h new file mode 100755 index 000000000000..652491b9408c --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rate.h @@ -0,0 +1,155 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rate.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm.h new file mode 100755 index 000000000000..0a7952f40dc6 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm.h @@ -0,0 +1,498 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/rlm.h#1 $ +*/ + +/*! \file "rlm.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 04 12 2011 cm.chang + * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency + * . + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + ); + +VOID +linkToRlmRspGenerateObssScanIE ( + P_ADAPTER_T prAdapter, + P_MSDU_INFO_T prMsduInfo + ); + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#ifndef _lint +__KAL_INLINE__ VOID +rlmDataTypeCheck ( + VOID + ) +{ +#if CFG_ENABLE_BT_OVER_WIFI + DATA_STRUC_INSPECTING_ASSERT( + NETWORK_TYPE_AIS_INDEX < NETWORK_TYPE_BOW_INDEX); + + #if CFG_ENABLE_WIFI_DIRECT + DATA_STRUC_INSPECTING_ASSERT( + NETWORK_TYPE_P2P_INDEX < NETWORK_TYPE_BOW_INDEX); + #endif +#endif + + return; +} +#endif /* _lint */ + +#endif /* _RLM_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_domain.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_domain.h new file mode 100755 index 000000000000..7e27be230959 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_domain.h @@ -0,0 +1,395 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/rlm_domain.h#1 $ +*/ + +/*! \file "rlm_domain.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm_domain.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 06 01 2011 cm.chang + * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function + * Provide function to check if specified channel is legal based on domain + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 channle 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 COUNTRY_CODE_NULL ((UINT_16)0x0) + +/* ISO/IEC 3166-1 two-character country codes */ +#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_AR (((UINT_16) 'A' << 8) | (UINT_16) 'T') /* Argentina */ +#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_BB (((UINT_16) 'B' << 8) | (UINT_16) 'B') /* Barbados */ +#define COUNTRY_CODE_BE (((UINT_16) 'B' << 8) | (UINT_16) 'E') /* Belgium */ +#define COUNTRY_CODE_BM (((UINT_16) 'B' << 8) | (UINT_16) 'M') /* Bermuda */ +#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_BY (((UINT_16) 'B' << 8) | (UINT_16) 'Y') /* Belarus */ +#define COUNTRY_CODE_CA (((UINT_16) 'C' << 8) | (UINT_16) 'A') /* Canada */ +#define COUNTRY_CODE_CH (((UINT_16) 'C' << 8) | (UINT_16) 'H') /* Switzerland */ +#define COUNTRY_CODE_CL (((UINT_16) 'C' << 8) | (UINT_16) 'L') /* Chile */ +#define COUNTRY_CODE_CN (((UINT_16) 'C' << 8) | (UINT_16) 'N') /* China */ +#define COUNTRY_CODE_CO (((UINT_16) 'C' << 8) | (UINT_16) 'O') /* Colombia */ +#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_DE (((UINT_16) 'D' << 8) | (UINT_16) 'E') /* Germany */ +#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_EC (((UINT_16) 'E' << 8) | (UINT_16) 'C') /* Ecuador */ +#define COUNTRY_CODE_EG (((UINT_16) 'E' << 8) | (UINT_16) 'G') /* Egypt */ +#define COUNTRY_CODE_ES (((UINT_16) 'E' << 8) | (UINT_16) 'S') /* Spain */ +#define COUNTRY_CODE_EU (((UINT_16) 'E' << 8) | (UINT_16) 'U') /* ETSI (Europe) */ +#define COUNTRY_CODE_FI (((UINT_16) 'F' << 8) | (UINT_16) 'I') /* Finland */ +#define COUNTRY_CODE_FR (((UINT_16) 'F' << 8) | (UINT_16) 'R') /* France */ +#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_GR (((UINT_16) 'G' << 8) | (UINT_16) 'R') /* Greece */ +#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_HT (((UINT_16) 'H' << 8) | (UINT_16) 'T') /* Haiti */ +#define COUNTRY_CODE_HN (((UINT_16) 'H' << 8) | (UINT_16) 'N') /* Honduras */ +#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_IN (((UINT_16) 'I' << 8) | (UINT_16) 'N') /* India */ +#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_JM (((UINT_16) 'J' << 8) | (UINT_16) 'M') /* Jamaica */ +#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_KN (((UINT_16) 'K' << 8) | (UINT_16) 'N') /* Saint Kitts and Nevis */ +#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_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_LU (((UINT_16) 'L' << 8) | (UINT_16) 'U') /* Luxembourg */ +#define COUNTRY_CODE_MA (((UINT_16) 'M' << 8) | (UINT_16) 'A') /* Morocco */ +#define COUNTRY_CODE_MD (((UINT_16) 'M' << 8) | (UINT_16) 'D') /* Moldova */ +#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_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_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_PE (((UINT_16) 'P' << 8) | (UINT_16) 'E') /* Peru */ +#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_PR (((UINT_16) 'P' << 8) | (UINT_16) 'R') /* Puerto Rico */ +#define COUNTRY_CODE_PT (((UINT_16) 'P' << 8) | (UINT_16) 'T') /* Portugal */ +#define COUNTRY_CODE_PY (((UINT_16) 'P' << 8) | (UINT_16) 'Y') /* Paraguay */ +#define COUNTRY_CODE_PZ (((UINT_16) 'P' << 8) | (UINT_16) 'Z') /* Panama */ +#define COUNTRY_CODE_RU (((UINT_16) 'R' << 8) | (UINT_16) 'U') /* Russian */ +#define COUNTRY_CODE_SA (((UINT_16) 'S' << 8) | (UINT_16) 'A') /* Saudi Arabia */ +#define COUNTRY_CODE_SE (((UINT_16) 'S' << 8) | (UINT_16) 'E') /* Sweden */ +#define COUNTRY_CODE_SG (((UINT_16) 'S' << 8) | (UINT_16) 'G') /* Singapore */ +#define COUNTRY_CODE_SR (((UINT_16) 'S' << 8) | (UINT_16) 'R') /* Suriname */ +#define COUNTRY_CODE_TW (((UINT_16) 'T' << 8) | (UINT_16) 'W') /* Taiwan */ +#define COUNTRY_CODE_TH (((UINT_16) 'T' << 8) | (UINT_16) 'H') /* Thailand */ +#define COUNTRY_CODE_TR (((UINT_16) 'T' << 8) | (UINT_16) 'R') /* Turkey */ +#define COUNTRY_CODE_TT (((UINT_16) 'T' << 8) | (UINT_16) 'T') /* Trinidad */ +#define COUNTRY_CODE_UA (((UINT_16) 'U' << 8) | (UINT_16) 'A') /* Ukraine */ +#define COUNTRY_CODE_US (((UINT_16) 'U' << 8) | (UINT_16) 'S') /* United States */ +#define COUNTRY_CODE_UY (((UINT_16) 'U' << 8) | (UINT_16) 'Y') /* Uruguay */ +#define COUNTRY_CODE_VC (((UINT_16) 'V' << 8) | (UINT_16) 'C') /* Saint Vincent */ +#define COUNTRY_CODE_VE (((UINT_16) 'V' << 8) | (UINT_16) 'E') /* Venezuela */ +#define COUNTRY_CODE_VN (((UINT_16) 'V' << 8) | (UINT_16) 'N') /* Vietnam */ + +/* 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 */ + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* 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; + +#if 0 +/* If channel width is CHNL_BW_20_40, 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 { + UINT_8 ucRegClass; + ENUM_BAND_T eBand; + ENUM_CHNL_SPAN_T eChannelSpan; + UINT_8 ucFirstChannelNum; + UINT_8 ucNumChannels; + ENUM_CHNL_BW_T eChannelBw; + BOOLEAN fgDfsNeeded; + BOOLEAN fgIbssProhibited; +} DOMAIN_SUBBAND_INFO, *P_DOMAIN_SUBBAND_INFO; + +/* Use it as all available channel list for STA */ +typedef struct _DOMAIN_INFO_ENTRY { + UINT_16 u2CountryCode; + UINT_16 u2MibRegDomainValue; + + /* 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; + +#else /* New definition 20110830 */ + +/* 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 ucReserved; /* Type: BOOLEAN (fgDfsNeeded) */ +} 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; +#endif + +/* The following definitions are not used yet */ +typedef enum _ENUM_CH_SET_2G4_T { + CH_SET_2G4_NA, + CH_SET_2G4_1_11, + CH_SET_2G4_1_13, + CH_SET_2G4_1_14, + CH_SET_2G4_NUM +} ENUM_CH_SET_2G4_T, *P_ENUM_CH_SET_2G4_T; + +typedef enum _ENUM_CH_SET_UNII_LOW_T { + CH_SET_UNII_LOW_NA, + CH_SET_UNII_LOW_36_48, + CH_SET_UNII_LOW_NUM +} ENUM_CH_SET_UNII_LOW_T, *P_ENUM_CH_SET_UNII_LOW_T; + +typedef enum _ENUM_CH_SET_UNII_MID_T { + CH_SET_UNII_MID_NA, + CH_SET_UNII_MID_52_64, + CH_SET_UNII_MID_NUM +} ENUM_CH_SET_UNII_MID_T, *P_ENUM_CH_SET_UNII_MID_T; + +typedef enum _ENUM_CH_SET_UNII_WW_T { + CH_SET_UNII_WW_NA, + CH_SET_UNII_WW_100_128, + CH_SET_UNII_WW_100_140, + CH_SET_UNII_WW_100_116_132_140, + CH_SET_UNII_WW_NUM +} ENUM_CH_SET_UNII_WW_T, *P_ENUM_CH_SET_UNII_WW_T; + +typedef enum _ENUM_CH_SET_UNII_UPPER_T { + CH_SET_UNII_UPPER_NA, + CH_SET_UNII_UPPER_149_161, + CH_SET_UNII_UPPER_149_165, + CH_SET_UNII_UPPER_149_173, + CH_SET_UNII_UPPER_NUM +} ENUM_CH_SET_UNII_UPPER_T, *P_ENUM_CH_SET_UNII_UPPER_T; + +typedef struct _COUNTRY_CH_SET_T { + ENUM_CH_SET_2G4_T e2G4; + ENUM_CH_SET_UNII_LOW_T eUniiLow; + ENUM_CH_SET_UNII_MID_T eUniiMid; + ENUM_CH_SET_UNII_WW_T eUniiWw; + ENUM_CH_SET_UNII_UPPER_T eUniiUpper; +} COUNTRY_CH_SET_T, *P_COUNTRY_CH_SET_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 +******************************************************************************** +*/ +P_DOMAIN_INFO_ENTRY +rlmDomainGetDomainInfo ( + P_ADAPTER_T prAdapter + ); + +VOID +rlmDomainGetChnlList ( + P_ADAPTER_T prAdapter, + ENUM_BAND_T eSpecificBand, + UINT_8 ucMaxChannelNum, + PUINT_8 pucNumOfChannel, + P_RF_CHANNEL_INFO_T paucChannelList + ); + +VOID +rlmDomainSendCmd ( + P_ADAPTER_T prAdapter, + BOOLEAN fgIsOid + ); + +BOOLEAN +rlmDomainIsLegalChannel ( + P_ADAPTER_T prAdapter, + ENUM_BAND_T eBand, + UINT_8 ucChannel + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _RLM_DOMAIN_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_obss.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_obss.h new file mode 100755 index 000000000000..b0ca5f16a59c --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_obss.h @@ -0,0 +1,208 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/rlm_obss.h#1 $ +*/ + +/*! \file "rlm_obss.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm_obss.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_protection.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_protection.h new file mode 100755 index 000000000000..0b12ff7981cd --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rlm_protection.h @@ -0,0 +1,170 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/rlm_protection.h#1 $ +*/ + +/*! \file "rlm_protection.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm_protection.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/roaming_fsm.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/roaming_fsm.h new file mode 100755 index 000000000000..71c54db250cc --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/roaming_fsm.h @@ -0,0 +1,245 @@ +/* +** $Id: +*/ + +/*! \file "roaming_fsm.h" + \brief This file defines the FSM for Roaming MODULE. + + This file defines the FSM for Roaming MODULE. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: roaming_fsm.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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; + +typedef struct _ROAMING_PARAM_T { + UINT_16 u2Event; + UINT_16 u2Data; +} 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; + +} 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 UINT_32 u4Param + ); + +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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rsn.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rsn.h new file mode 100755 index 000000000000..5753efab4f12 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/rsn.h @@ -0,0 +1,424 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/rsn.h#1 $ +*/ + +/*! \file rsn.h + \brief The wpa/rsn related define, macro and structure are described here. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rsn.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 / WPA/ RSN IE structure to mac.h and some SW structure not align at byte. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + ); + +#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 UINT_32 u4Parm + ); +#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 +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _RSN_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/scan.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/scan.h new file mode 100755 index 000000000000..1d6e4eb07903 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/scan.h @@ -0,0 +1,896 @@ +/* +** $Id: @(#) +*/ + +/*! \file "scan.h" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 extention 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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. + */ + +#define SCN_BSS_DESC_REMOVE_TIMEOUT_SEC 5 // 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. + +/*----------------------------------------------------------------------------*/ +/* 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 4 + + +/******************************************************************************* +* 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; + + + +/*----------------------------------------------------------------------------*/ +/* 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; + BOOL fgIEWAPI; +#endif + BOOL fgIERSN; + BOOL 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; + 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 u2IELength; /* The byte count of aucIEBuf[] */ + + ULARGE_INTEGER u8TimeStamp; /* Place u8TimeStamp before aucIEBuf[1] to force DW align */ + + UINT_8 aucIEBuf[CFG_IE_BUFFER_SIZE]; +}; + + +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 _SCAN_INFO_T { + ENUM_SCAN_STATE_T eCurrentState; /* Store the STATE variable of SCAN FSM */ + + OS_SYSTIME rLastScanCompletedTime; + + SCAN_PARAM_T rScanParam; + + 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; + +} 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; + +/******************************************************************************* +* P U B 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 + ); + + +/* 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 + ); + +/*----------------------------------------------------------------------------*/ +/* Routines in scan_fsm.c */ +/*----------------------------------------------------------------------------*/ +VOID +scnFsmSteps ( + IN P_ADAPTER_T prAdapter, + IN ENUM_SCAN_STATE_T eNextState + ); + +/*----------------------------------------------------------------------------*/ +/* Command Routines */ +/*----------------------------------------------------------------------------*/ +VOID +scnSendScanReq ( + 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 + ); + +/*----------------------------------------------------------------------------*/ +/* 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 + ); + + +#endif /* _SCAN_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/sec_fsm.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/sec_fsm.h new file mode 100755 index 000000000000..e887cff4115a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/sec_fsm.h @@ -0,0 +1,328 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: sec_fsm.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 UINT_32 u4Parm + ); + +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 UINT_32 u4Parm + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _SEC_FSM_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/swcr.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/swcr.h new file mode 100755 index 000000000000..4afb42d358df --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/swcr.h @@ -0,0 +1,220 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/swcr.h#1 $ +*/ + +/*! \file "swcr.h" + \brief +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* + * + */ + +#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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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) \ + index = action & 0x7F; \ + rw = action >> 7; + + +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 +******************************************************************************** +*/ + + +/******************************************************************************* +* 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wapi.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wapi.h new file mode 100755 index 000000000000..a587627b2a7e --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wapi.h @@ -0,0 +1,164 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/mgmt/wapi.h#1 $ +*/ + +/*! \file wapi.h + \brief The wapi related define, macro and structure are described here. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: wapi.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wlan_typedef.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wlan_typedef.h new file mode 100755 index 000000000000..f0fcdd30c9f6 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/mgmt/wlan_typedef.h @@ -0,0 +1,128 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: wlan_typedef.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk +*/ + +#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; + + +/* 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; + +/******************************************************************************* +* P U B 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/mtk_wcn_combo/drv_wlan/wlan/include/nic/adapter.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/adapter.h new file mode 100755 index 000000000000..40217c119637 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/adapter.h @@ -0,0 +1,1447 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/adapter.h#6 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: adapter.h $ + * + * 02 22 2012 yuche.tsai + * [ALPS00240483] [Wifi P2P]Run Sigma tool of A69. Always run fail on 5.1.2. No get correct connection from Realtek. + * Fix assoc response without P2P IE issue for Sigma test. + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 01 28 2012 yuche.tsai + * NULL + * Update for Beacon composing code but not active yet. + * + * 01 20 2012 chinglan.wang + * NULL + * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug. + * + * 01 16 2012 yuche.tsai + * NULL + * Update Driver for wifi driect gc join IE update issue. + * + * 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 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 class 3 error issue under AP mode. + * + * data frame may TX before Assoc Response TX. + * + * 11 19 2011 yuche.tsai + * NULL + * Add P2P RSSI Link Quality Query Support. (Default Off) + * + * 11 11 2011 yuche.tsai + * NULL + * Fix work thread cancel issue. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Add device discoverability support. (Phase I) + * + * 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 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 Netwrok. + * + * 03 19 2011 yuche.tsai + * [WCXRP00000581] [Volunteer Patch][MT6620][Driver] P2P IE in Assoc Req Issue + * Append P2P IE in assoc request if P2P is enabled. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) Chnage 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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; + 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_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 + BOOL 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; + +} 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 */ + + BOOLEAN ucSSIDLen; /* Length of SSID */ + 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 */ +}; + + +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; + +#if CFG_SLT_SUPPORT + SLT_INFO_T rSltInfo; +#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; + KAL_P2P_GET_CIPHER prKalP2pGetCipher; + KAL_P2P_GET_TKIP_CIPHER prKalP2pGetTkipCipher; + KAL_P2P_GET_CCMP_CIPHER prKalP2pGetCcmpCipher; + KAL_P2P_GET_WSC_MODE prKalP2pGetWscMode; + KAL_P2P_GET_DEV_HDLR prKalP2pGetDevHdlr; +// NIC_P2P_MEDIA_STATE_CHANGE prNicP2pMediaStateChange; + KAL_P2P_UPDATE_ASSOC_INFO prKalP2pUpdateAssocInfo; + P2P_VALIDATE_AUTH prP2pValidateAuth; + P2P_VALIDATE_ASSOC_REQ prP2pValidateAssocReq; + P2P_RUN_EVENT_AAA_TX_FAIL prP2pRunEventAAATxFail; + P2P_RUN_EVENT_AAA_COMPLETE prP2pRunEventAAASuccess; + P2P_RUN_EVENT_AAA_COMPLETE prP2pRunEventAAAComplete; + P2P_PARSE_CHECK_FOR_P2P_INFO_ELEM prP2pParseCheckForP2pInfoElem; +// SCAN_UPDATE_P2P_DEVICE_DESC prScanUpdateP2pDeviceDesc; +// P2P_FSM_RUN_EVENT_RX_PROBE_RESPONSE_FRAME prP2pFsmRunEventRxProbeResponseFrame; + P2P_PROCESS_EVENT_UPDATE_NOA_PARAM prP2pProcessEvent_UpdateNOAParam; + SCAN_P2P_PROCESS_BEACON_AND_PROBE_RESP prScanP2pProcessBeaconAndProbeResp; + P2P_RX_PUBLIC_ACTION_FRAME prP2pRxPublicActionFrame; + RLM_RSP_GENERATE_OBSS_SCAN_IE prRlmRspGenerateObssScanIE; + RLM_PROCESS_PUBLIC_ACTION prRlmProcessPublicAction; + RLM_PROCESS_HT_ACTION prRlmProcessHtAction; + RLM_UPDATE_PARAMS_FOR_AP prRlmUpdateParamsForAp; + RLM_HANDLE_OBSS_STATUS_EVENT_PKT prRlmHandleObssStatusEventPkt; + P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForBeacon; + P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForBeacon; + P2P_CALCULATE_P2P_IE_LEN prP2pCalculateP2p_IELenForAssocRsp; + P2P_GENERATE_P2P_IE prP2pGenerateP2p_IEForAssocRsp; + P2P_CALCULATE_P2P_IE_LEN prP2pCalculateWSC_IELenForBeacon; + 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; + P2P_FUNC_VALIDATE_PROBE_REQ prP2pFuncValidateProbeReq; + RLM_BSS_INIT_FOR_AP prRlmBssInitForAP; + P2P_GET_PROB_RSP_IE_TABLE_SIZE prP2pGetTxProbRspIETAbleSize; + P2P_BUILD_REASSOC_REQ_FRAME_COMMON_IES prP2pBuildReassocReqFrameCommIEs; +// SCAN_REMOVE_P2P_BSS_DESC prScanRemoveP2pBssDesc; + P2P_FUNC_DISCONNECT prP2pFuncDisconnect; + P2P_FSM_RUN_EVENT_RX_DEAUTH prP2pFsmRunEventRxDeauthentication; + P2P_FSM_RUN_EVENT_RX_DISASSOC prP2pFsmRunEventRxDisassociation; +// P2P_HANDLE_SEC_CHECK_RSP prP2pHandleSecCheckRsp; + P2P_FUN_IS_AP_MODE prP2pFuncIsApMode; + P2P_FSM_RUN_EVENT_BEACON_TIMEOUT prP2pFsmRunEventBeaconTimeout; + P2P_RX_PUBLIC_ACTION_FRAME prP2pRxActionFrame; + KAL_P2P_SET_MULTICAST_WORK_ITEM prP2pSetMulticastListWorkQueue; + P2P_FUNC_STORE_ASSOC_RSP_IE_BUFFER prP2pFuncStoreAssocRspIeBuffer; + P2P_CALCULATE_P2P_IE_LEN prP2pCalculate_IELenForAssocReq; + P2P_GENERATE_P2P_IE prP2pGenerate_IEForAssocReq; +} P2P_FUNCTION_LINKER, *P_P2P_FUNCTION_LINKER; + + +#endif + +/* + * Major ADAPTER structure + * Major data structure for driver operation + */ +struct _ADAPTER_T { + UINT_8 ucRevID; + + UINT_16 u2NicOpChnlNum; + + BOOLEAN fgIsEnableWMM; + BOOLEAN fgIsWmmAssoc; /* This flag is used to indicate that WMM is enable in current BSS */ + + UINT_32 u4OsPacketFilter; // packet filter used by OS + + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + UINT_32 u4CSUMFlags; +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + + ENUM_BAND_T aePreferBand[NETWORK_TYPE_INDEX_NUM]; + + /* ADAPTER flags */ + UINT_32 u4Flags; + UINT_32 u4HwFlags; + + BOOLEAN fgIsRadioOff; + + BOOLEAN fgIsEnterD3ReqIssued; + + UINT_8 aucMacAddress[MAC_ADDR_LEN]; + + ENUM_PHY_TYPE_INDEX_T eCurrentPhyType; /* Current selection basing on the set of Available PHY Types */ + +#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG + UINT_32 u4CoalescingBufCachedSize; + PUINT_8 pucCoalescingBufCached; +#endif /* CFG_COALESCING_BUFFER_SIZE */ + + /* Buffer for CMD_INFO_T, Mgt packet and mailbox message */ + BUF_INFO_T rMgtBufInfo; + BUF_INFO_T rMsgBufInfo; + PUINT_8 pucMgtBufCached; + UINT_32 u4MgtBufCachedSize; + UINT_8 aucMsgBuf[MSG_BUFFER_SIZE]; +#if CFG_DBG_MGT_BUF + UINT_32 u4MemAllocDynamicCount; /* Debug only */ + UINT_32 u4MemFreeDynamicCount; /* Debug only */ +#endif + + STA_RECORD_T arStaRec[CFG_STA_REC_NUM]; + + /* Element for TX PATH */ + TX_CTRL_T rTxCtrl; + QUE_T rFreeCmdList; + CMD_INFO_T arHifCmdDesc[CFG_TX_MAX_CMD_PKT_NUM]; + + /* Element for RX PATH */ + RX_CTRL_T rRxCtrl; + + P_SDIO_CTRL_T prSDIOCtrl; + +#if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1) + /* Element for MT6620 E1 HIFSYS workaround */ + BOOLEAN fgIsClockGatingEnabled; +#endif + + /* Buffer for Authentication Event */ + /* Move to glue layer and refine the kal function */ + /* Reference to rsnGeneratePmkidIndication function at rsn.c */ + UINT_8 aucIndicationEventBuffer[(CFG_MAX_PMKID_CACHE * 20) + 8 ]; + + UINT_32 u4IntStatus; + + ENUM_ACPI_STATE_T rAcpiState; + + BOOLEAN fgIsIntEnable; + BOOLEAN fgIsIntEnableWithLPOwnSet; + + BOOLEAN fgIsFwOwn; + BOOLEAN fgWiFiInSleepyState; + + UINT_32 u4PwrCtrlBlockCnt; + + QUE_T rPendingCmdQueue; + + P_GLUE_INFO_T prGlueInfo; + + UINT_8 ucCmdSeqNum; + UINT_8 ucTxSeqNum; + +#if 1//CFG_SUPPORT_WAPI + BOOLEAN fgUseWapi; +#endif + + /* RF Test flags */ + BOOLEAN fgTestMode; + + /* WLAN Info for DRIVER_CORE OID query */ + WLAN_INFO_T rWlanInfo; + +#if CFG_ENABLE_WIFI_DIRECT + BOOLEAN fgIsP2PRegistered; + BOOLEAN fgIsWlanLaunched; + P_P2P_INFO_T prP2pInfo; + P2P_FUNCTION_LINKER rP2pFuncLkr; +#if CFG_SUPPORT_P2P_RSSI_QUERY + OS_SYSTIME rP2pLinkQualityUpdateTime; + BOOLEAN fgIsP2pLinkQualityValid; + EVENT_LINK_QUALITY rP2pLinkQuality; +#endif +#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; + + /* 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; + + /* Packet Forwarding Tracking */ + INT_32 i4PendingFwdFrameCount; + +#if CFG_SUPPORT_RDD_TEST_MODE + UINT_8 ucRddStatus; +#endif + +};/* 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 +******************************************************************************** +*/ +/*----------------------------------------------------------------------------*/ +/* 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 + +/*----------------------------------------------------------------------------*/ +/* 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/mtk_wcn_combo/drv_wlan/wlan/include/nic/bow.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/bow.h new file mode 100755 index 000000000000..c435fdc99236 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/bow.h @@ -0,0 +1,366 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/bow.h#1 $ +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: bow.h $ + * + * 02 16 2012 chinghwa.yu + * [ALPS00238061] [Need Patch] [Volunteer Patch] 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 + * Add new feature - multiple physical link support. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +#define MAX_BOW_NUMBER_OF_CHANNEL 18 //(MAX_BOW_NUMBER_OF_CHANNEL_2G4 + MAX_BOW_NUMBER_OF_CHANNEL_5G) + +#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/mtk_wcn_combo/drv_wlan/wlan/include/nic/cmd_buf.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/cmd_buf.h new file mode 100755 index 000000000000..1dcae5533bf0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/cmd_buf.h @@ -0,0 +1,220 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: cmd_buf.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + ); + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _CMD_BUF_H */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hal.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hal.h new file mode 100755 index 000000000000..df4f0fa3b04e --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hal.h @@ -0,0 +1,654 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/hal.h#1 $ +*/ + +/*! \file "hal.h" + \brief The declaration of hal functions + + N/A +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: hal.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 04 01 2011 tsaiyuan.hsu + * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues + * fix the klocwork issues, 57500, 57501, 57502 and 57503. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) \ + { \ + 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", _u4Offset, *_pu4Value)); \ + } \ + } else { \ + DBGLOG(HAL, WARN, ("ignore HAL_MCR_RD access! 0x%x\n", _u4Offset)); \ + } \ + } + +#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ + { \ + 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", _u4Offset, _u4Value)); \ + } \ + } else { \ + DBGLOG(HAL, WARN, ("ignore HAL_MCR_WR access! 0x%x: 0x%x \n", _u4Offset, _u4Value)); \ + } \ + } + +#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)); \ + } \ + } + +#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 { \ + } \ + } \ + else { \ + DBGLOG(HAL, WARN, ("ignore HAL_BYTE_WR access! 0x%x\n", _u4Port)); \ + } \ + } + + +#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); \ + } \ + kalDevRegRead(_prAdapter->prGlueInfo, _u4Offset, _pu4Value); \ + } + +#define HAL_MCR_WR(_prAdapter, _u4Offset, _u4Value) \ + { \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevRegWrite(_prAdapter->prGlueInfo, _u4Offset, _u4Value); \ + } + +#define HAL_PORT_RD(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ + { \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevPortRead(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize); \ + } + +#define HAL_PORT_WR(_prAdapter, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize) \ + { \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevPortWrite(_prAdapter->prGlueInfo, _u4Port, _u4Len, _pucBuf, _u4ValidBufSize); \ + } + +#define HAL_BYTE_WR(_prAdapter, _u4Port, _ucBuf) \ + { \ + if (_prAdapter->rAcpiState == ACPI_STATE_D3) { \ + ASSERT(0); \ + } \ + kalDevWriteWithSdioCmd52(_prAdapter->prGlueInfo, _u4Port, _ucBuf); \ + } + +#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/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_emu.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_emu.h new file mode 100755 index 000000000000..7a74a00ab4ba --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_emu.h @@ -0,0 +1,308 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/hif_emu.h#1 $ +*/ +/*! \file hif.h" + \brief Sdio specific structure for GLUE layer on WinXP + + Sdio specific structure for GLUE layer on WinXP +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: hif_emu.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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\6 2009-11-04 14:11:18 GMT mtk01084 +** add new test func +** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-10-30 18:17:42 GMT mtk01084 +** modify return value +** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-10-29 19:50:45 GMT mtk01084 +** add emu test cases +** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-10-23 16:08:54 GMT mtk01084 +** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-10-23 16:08:16 GMT mtk01084 +** \main\maintrunk.MT6620WiFiDriver_Prj\1 2009-10-13 21:27:05 GMT mtk01084 +** +*/ + +#ifndef _HIF_EMU_H +#define _HIF_EMU_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 +{ + HIF_TC_MBOX_LB = 0x100, + HIF_TC_SW_INT, + HIF_TC_COUNT_INCREASE, + HIF_TC_COUNT_RESET, + HIF_TC_TX_SINGLE_PACKET, + HIF_TC_TX_AGG_PACKET, + HIF_TC_TX_CLEAR_TC_COUNT, + HIF_TC_TX_CHK_STATE, + HIF_TC_RX_SINGLE_PACKET = 0x200, + HIF_TC_RX_PACKET_LEN, + HIF_TC_RX_PACKET_LEN_OVERFLOW, + HIF_TC_RX_AGG_PACKET, + HIF_TC_RX_CHK_STATE, + HIF_TC_RX_SW_PKT_FORMAT, + HIF_TC_RX_READ_HALF, + HIF_TC_MIX_TX_RX_STRESS, + HIF_TC_INTR_ENHANCE, + HIF_TC_RX_ENHANCE_MODE, + HIF_TC_TX_BURST, + HIF_TC_RX_BURST, +} HIF_TEST_CASE; + +#define HIF_TEST_CASE_START BIT(16) + + +/******************************************************************************* +* P U B 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 +emuInit ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuStart ( + IN P_ADAPTER_T prAdapter + ); + + +BOOLEAN +emuInitChkCis ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuMailboxLoopback ( + IN P_ADAPTER_T prAdapter, + IN BOOLEAN fgReadClearChk + ); + +BOOLEAN +emuSoftwareInterruptLoopback ( + IN P_ADAPTER_T prAdapter, + IN BOOLEAN fgIntrReadClear + ); + +BOOLEAN +emuCheckTxCount ( + IN P_ADAPTER_T prAdapter, + IN BOOLEAN fgReadByIntrEnhanMode + ); + +BOOLEAN +emuSendPacket1 ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4PortId, + IN BOOLEAN fgUseEnhanceModeRead + ); + +BOOLEAN +emuSendPacketAggN ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4PortId, + IN UINT_32 u4AggNum, + IN UINT_32 u4LenStart, + IN UINT_32 u4LenEnd, + IN BOOLEAN fgUseIntrEnhanceModeRead + ); + +BOOLEAN +emuReadHalfRxPacket ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuLPown_ownback_stress ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4LoopCount + ); + +BOOLEAN +emuLPown_illegal_access ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuIntrEnhanceChk ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuResetTxCount ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuChkTxState ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuChkRxState ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuRxPacket1 ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4PortId, + IN UINT_32 u4RxLen, + IN BOOLEAN fgEnIntrEnhanceMode, + IN BOOLEAN fgEnRxEnhanceMode, + IN BOOLEAN fgMBoxReadClearByRxEnhance + ); + +BOOLEAN +emuRxPacketLenChk ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuRxPacketAggN ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4PortId, + IN BOOLEAN fgEnRxEnhanceMode, + IN UINT_32 u4RxLen, + IN UINT_32 u4AggNum, + IN UINT_32 u4MaxReadAggNum//0: unlimited + ); + +BOOLEAN +emuRxPacketSwHdrFormat ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4PortId, + IN UINT_32 u4RxLen, + IN UINT_32 u4Num + ); + +BOOLEAN +emuRxPacketLenOverflow ( + IN P_ADAPTER_T prAdapter + ); + +BOOLEAN +emuTxPacketBurstInSwHdrFormat ( + IN P_ADAPTER_T prAdapter, + IN BOOLEAN fgEnable + ); + +BOOLEAN +emuRxPacketBurstInSwHdrFormat ( + IN P_ADAPTER_T prAdapter, + IN BOOLEAN fgEnable + ); + +BOOLEAN +emuSendPacketAggNSwHdrFormat ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4PortId, + IN UINT_32 u4LenStart + ); + +#define RUN_TEST_CASE(_Fmt) \ + { \ + if (status == FALSE) { \ + break; \ + } \ + if (_Fmt == FALSE) { \ + status = FALSE; \ + break; \ + } \ + } +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _HIF_EMU_H */ + + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_rx.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_rx.h new file mode 100755 index 000000000000..5f9303969ecb --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_rx.h @@ -0,0 +1,271 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/hif_rx.h#1 $ +*/ + +/*! \file "hif_rx.h" + \brief Provide HIF RX Header Information between F/W and Driver + + N/A +*/ +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: hif_rx.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) + +// 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_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 +******************************************************************************** +*/ +__KAL_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. + */ +__KAL_INLINE__ VOID +hifDataTypeCheck ( + VOID + ) +{ + DATA_STRUC_INSPECTING_ASSERT(sizeof(HIF_RX_HEADER_T) == 12); + + return; +} + +#endif diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_tx.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_tx.h new file mode 100755 index 000000000000..bf1c823451b9 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/hif_tx.h @@ -0,0 +1,269 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/hif_tx.h#1 $ +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: hif_tx.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) + + +/******************************************************************************* +* 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. + */ +__KAL_INLINE__ VOID +hif_txDataTypeCheck ( + VOID + ); + +__KAL_INLINE__ VOID +hif_txDataTypeCheck ( + VOID + ) +{ + DATA_STRUC_INSPECTING_ASSERT(sizeof(HIF_TX_HEADER_T) == 16); + + return; +} + +#endif /*_HIF_TX_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mac.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mac.h new file mode 100755 index 000000000000..2253263bdc6f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mac.h @@ -0,0 +1,2178 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/mac.h#2 $ +*/ + +/*! \file "mac.h" + \brief Brief description. + + Detail description. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: mac.h $ + * + * 01 16 2012 yuche.tsai + * NULL + * Update Driver for wifi driect gc join IE update issue. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 / WPA/ RSN IE structure to mac.h and some SW structure not align at byte. + * + * 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 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Add device discoverability support. (Phase I) + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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_PROTOCOL_OFFSET 9 +#define IPV4_HDR_IP_CSUM_OFFSET 10 + +#define IPV6_HDR_IP_PROTOCOL_OFFSET 6 + +#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 32 + + +//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 */ + +/* 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 becasue 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_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 */ +#if CFG_SUPPORT_802_11W +#define ELEM_ID_TIMEOUT_INTERVAL 56 /* 802.11w SA Timeout interval */ +#endif +#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_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_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 + +/* 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 + + +/* 7.3.2.25 RSN information element */ +#define ELEM_MAX_LEN_WPA 24 /* 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_MAX_LEN_EXT_CAP (3 - ELEM_HDR_LEN) + +/* 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) //WMM: Bit(7,8) = (1,0) = EDCA +#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) + + +//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 */ + +//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_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 + + +//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; + +/* 7.3.2.20 Channel Switch Announcement element */ +typedef struct _IE_CHNL_SWITCH_T { + UINT_8 ucId; + UINT_8 ucLength; + UINT_8 ucSwitchMode; + UINT_8 ucNewChannel; + UINT_8 ucSwitchCount; +} __KAL_ATTRIB_PACKED__ IE_CHNL_SWITCH_T, *P_IE_CHNL_SWITCH_T; + +/* 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[1]; +} __KAL_ATTRIB_PACKED__ IE_EXT_CAP_T, *P_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.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; + + +//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.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; + +//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; + +/* 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 QUIET_IE(fp) ((P_IE_QUIET_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)) + +/******************************************************************************* +* 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/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt5931_reg.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt5931_reg.h new file mode 100755 index 000000000000..1c75d2d03a27 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt5931_reg.h @@ -0,0 +1,340 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/mt5931_reg.h#1 $ +*/ + +/*! \file "mt5931_reg.h" + \brief The common register definition of mt5931 + + N/A +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: mt5931_reg.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 18 2011 terry.wu + * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log + * Add WHISR_D2H_SW_ASSERT_INFO_INT to MT5931_reg. + * + * 10 07 2010 cp.wu + * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection + * add firmware download for MT5931. + * +*/ + +#ifndef _MT5931_REG_H +#define _MT5931_REG_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 MT5931 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 EHPI Transaction Count Register +#define MCR_EHTCR 0x0054 + +//4 Firmware Download Data Register +#define MCR_FWDLDR 0x0080 + +//4 Firmware Download Destination Starting Address Register +#define MCR_FWDLDSAR 0x0084 + +//4 Firmware Download Status Register +#define MCR_FWDLSR 0x0088 + +//4 WLAN MCU Control & Status Register +#define MCR_WMCSR 0x008c + +//4 WLAN Firmware Download Configuration +#define MCR_FWCFG 0x0090 + + +//#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 0x00005931 +#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 FWDLSR 0x0088 +#define FWDLSR_FWDL_RDY BIT(8) +#define FWDLSR_FWDL_MODE BIT(0) + + +//3 WMCSR 0x008c +#define WMCSR_CHIP_RST BIT(15) /* write */ +#define WMCSR_DL_OK BIT(15) /* read */ +#define WMCSR_DL_FAIL BIT(14) +#define WMCSR_PLLRDY BIT(13) +#define WMCSR_WF_ON BIT(12) +#define WMCSR_INI_RDY BIT(11) +#define WMCSR_WF_EN BIT(6) +#define WMCSR_SW_EN BIT(5) +#define WMCSR_SPLLEN BIT(4) +#define WMCSR_SPWREN BIT(3) +#define WMCSR_HSTOPIL BIT(2) +#define WMCSR_FWDLRST BIT(1) +#define WMCSR_FWDLEN BIT(0) + + +//3 FWCFG 0x0090 +#define FWCFG_KSEL BITS(14,15) +#define FWCFG_FLEN BITS(0,13) + + +#endif /* _MT5931_REG_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt6620_reg.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt6620_reg.h new file mode 100755 index 000000000000..44c3fa0b19d3 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/mt6620_reg.h @@ -0,0 +1,330 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/mt6620_reg.h#1 $ +*/ + +/*! \file "mt6620_reg.h" + \brief The common register definition of mt6620 + + N/A +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: mt6620_reg.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + * + * 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 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 +** \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-12-10 16:44:18 GMT mtk02752 +** remove 5921 definitions +** \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-11-09 22:56:32 GMT mtk01084 +** modify HW register definitions +** \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-11-04 14:11:04 GMT mtk01084 +** modify default IER bits +** \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-10-29 19:52:32 GMT mtk01084 +** modify data struture +** \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-10-23 16:08:20 GMT mtk01084 +** \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-10-13 21:58:53 GMT mtk01084 +** update for new HW architecture design +** \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-09-09 17:26:11 GMT mtk01084 +** add CFG_TEST_WITH_MT5921 +** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-05-18 20:59:57 GMT mtk01426 +** Update WHIER_DEFAULT value +** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-05-07 16:57:36 GMT mtk01426 +** Update CHIP ID to 0x6620, and WHLPCR bit definition +** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-28 10:34:57 GMT mtk01461 +** Add read WTSR and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode +** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-24 09:46:52 GMT mtk01084 +** fix LINT error +** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-23 00:32:24 GMT mtk01461 +** Define constants for TX PATH +** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-18 20:54:10 GMT mtk01426 +** Add WHCR_MAX_HIF_RX_AGG_LEN_OFFSET definition +** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:16:29 GMT mtk01426 +** Init for develop +** +*/ + +#ifndef _MT6620_REG_H +#define _MT6620_REG_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 MT6620 MCR Definition + +//2 Host Interface + +//4 CHIP ID Register +#define MCR_WCIR 0x0000 + +//4 HIF Low Power Control Register +#define MCR_WHLPCR 0x0004 +//#define MCR_WHLPCR_BYTE1 0x0005 + + +//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 WLAN RX Packet Length Register +#define MCR_WRPLR 0x0048 + + + + +//temp //#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 0x00006620 +#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_INT_INDICATOR BIT(7) +#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_INT_INDICATOR_EN BIT(7) +#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 WTSR0 0x0044 +#define WRPLR_RX1_PACKET_LENGTH BITS(16,31) +#define WRPLR_RX0_PACKET_LENGTH BITS(0,15) + +#endif /* _MT6620_REG_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic.h new file mode 100755 index 000000000000..5b1e51cf14ad --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic.h @@ -0,0 +1,764 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/nic.h#1 $ +*/ + +/*! \file "nic.h" + \brief The declaration of nic functions + + Detail description. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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.. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 after WLAN module removed. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 occured + * + * 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 +******************************************************************************** +*/ + +/******************************************************************************* +* P U B 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 + ); + +BOOL +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 + ); + + +/*----------------------------------------------------------------------------*/ +/* 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 + ); + +/*----------------------------------------------------------------------------*/ +/* 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/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_rx.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_rx.h new file mode 100755 index 000000000000..c872e8f3b35f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_rx.h @@ -0,0 +1,577 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/nic_rx.h#1 $ +*/ + +/*! \file "nic_rx.h" + \brief The declaration of the nic rx functions + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic_rx.h $ + * + * 11 04 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 Xlog debugging. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 06 27 2011 tsaiyuan.hsu + * [WCXRP00000816] [MT6620 Wi-Fi][Driver] add control to enable rx data dump or not + * add control to enable rx data dump by packet type. + * + * 04 18 2011 terry.wu + * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED + * Remove flag CFG_WIFI_DIRECT_MOVED. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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 + + +#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 */ +}; + +/*! 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) \ + ((BOOL)((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 + ); + +#if defined(MT5931) +VOID +nicRxPostInitialize ( + IN P_ADAPTER_T prAdapter + ); +#endif + +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/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_tx.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_tx.h new file mode 100755 index 000000000000..590fb18494e4 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/nic_tx.h @@ -0,0 +1,679 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic_tx.h $ + * + * 11 19 2011 eddie.chen + * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) + * Add xlog for tx + * + * 11 10 2011 eddie.chen + * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) + * Add TX_DONE status detail information. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 02 16 2011 cp.wu + * [WCXRP00000449] [MT6620 Wi-Fi][Driver] Refine CMD queue handling by adding an extra API for checking availble 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(MT5931) || defined(MT6628) + #define NIC_TX_BUFF_COUNT_TC0 1 // First connection: 0 + #define NIC_TX_BUFF_COUNT_TC1 14 // 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 +#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 + +/******************************************************************************* +* 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; + +/* 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 + ); + +/* 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; +}; + + +/******************************************************************************* +* P U B 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));} + + + +/******************************************************************************* +* 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 + ); + +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/mtk_wcn_combo/drv_wlan/wlan/include/nic/que_mgt.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/que_mgt.h new file mode 100755 index 000000000000..68931e663cb2 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/que_mgt.h @@ -0,0 +1,1185 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: que_mgt.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 07 2011 eddie.chen + * [WCXRP00000527] [MT6620 Wi-Fi][FW/Driver] Clean buffered packet when BSS is inactive or disconnected + * Add functino to remove broadcast and unknown packets. + * + * 04 07 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) Chnage 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 */ +#define QM_BURST_END_INFO_ENABLED 1 /* 1: Indicate the last TX packet to the FW for each burst */ +#define QM_FORWARDING_FAIRNESS 1 /* 1: To fairly share TX resource among active STAs */ +#define QM_ADAPTIVE_TC_RESOURCE_CTRL 1 /* 1: To adaptively adjust resource for each TC */ +#define QM_PRINT_TC_RESOURCE_CTRL 0 /* 1: To print TC resource adjustment results */ +#define QM_RX_WIN_SSN_AUTO_ADVANCING 1 /* 1: If pkt with SSN is missing, auto advance the RX reordering window */ +#define QM_RX_INIT_FALL_BEHIND_PASS 1 /* 1: Indicate the packets falling behind to OS before the frame with SSN is received */ +/* Parameters */ +#define QM_INIT_TIME_TO_UPDATE_QUE_LEN 60 /* p: Update queue lengths when p TX packets are enqueued */ +#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(MT5931) || defined(MT6628) + +#define QM_GUARANTEED_TC0_RESOURCE 4 +#define QM_GUARANTEED_TC1_RESOURCE 4 +#define QM_GUARANTEED_TC2_RESOURCE 4 +#define QM_GUARANTEED_TC3_RESOURCE 4 +#define QM_GUARANTEED_TC4_RESOURCE 2 /* Resource for TC4 is not adjustable */ +#define QM_GUARANTEED_TC5_RESOURCE 2 + +#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 */ +#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 */ + + + +/******************************************************************************* +* 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; + + /* 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 + + + + +} 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_TYEP_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 + ); + +VOID +qmPopOutDueToFallWithin( + IN P_RX_BA_ENTRY_T prReorderQueParm, + OUT P_QUE_T prReturnedQue + ); + +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 + ); + +BOOL +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 + ); + +VOID +mqmGenerateWmmInfoIE ( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ); + +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 + ); + +VOID +qmFreeAllByNetType( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx + ); + +UINT_32 +qmGetRxReorderQueuedBufferCount( + IN P_ADAPTER_T prAdapter + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _QUE_MGT_H */ diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/wlan_def.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/wlan_def.h new file mode 100755 index 000000000000..9ddf0e94b187 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic/wlan_def.h @@ -0,0 +1,1056 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/nic/wlan_def.h#1 $ +*/ + +/*! \file "wlan_def.h" + \brief This file includes the basic definition of WLAN + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: wlan_def.h $ + * + * 12 06 2011 cp.wu + * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path + * sync. for connect-by-bssid control path implementations. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 / WPA/ RSN IE structure to mac.h and some SW structure not align at byte. + * + * 04 07 2011 eddie.chen + * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma + * Fix for sigma. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + +/* 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_DLS_INDEX +} 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_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 { + PHY_CONFIG_802_11ABG = 0, /*!< Can associated with 802.11abg AP but without n capability, Scan dual band. */ + 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) + +/* 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) + +/* 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) +} 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/mtk_wcn_combo/drv_wlan/wlan/include/nic_cmd_event.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic_cmd_event.h new file mode 100755 index 000000000000..27332fd039c3 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic_cmd_event.h @@ -0,0 +1,1824 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic_cmd_event.h $ + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 11 19 2011 yuche.tsai + * NULL + * Add P2P RSSI Link Quality Query Support. (Default 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 avoid compiler error. + * + * 11 04 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 Xlog 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. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * + * 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 + * follow-ups for frequency-shifted WAPI AP support + * + * 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 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 extention 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 occured + * + * 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 + + +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_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_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 + +#if CFG_SUPPORT_RDD_TEST_MODE + CMD_ID_SET_RDD_CH = 0xE1, +#endif + + CMD_ID_SET_BWCS = 0xF1, +#if CFG_SUPPORT_OSC_SETTING && defined(MT5931) + CMD_ID_SET_OSC = 0xf2, +#endif +} 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 +} 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 +/* 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_STRUC_T rRfATInfo; + } u; +} CMD_TEST_CTRL_T, *P_CMD_TEST_CTRL_T; + +// EVENT_TEST_STATUS +typedef struct _PARAM_CUSTOM_RFTEST_TX_STATUS_STRUC_T { + UINT_32 u4PktSentStatus; + UINT_32 u4PktSentCount; + UINT_16 u2AvgAlc; + UINT_8 ucCckGainControl; + UINT_8 ucOfdmGainControl; +} PARAM_CUSTOM_RFTEST_TX_STATUS_STRUC_T, *P_PARAM_CUSTOM_RFTEST_TX_STATUS_STRUC_T; + +typedef struct _PARAM_CUSTOM_RFTEST_RX_STATUS_STRUC_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_STRUC_T, *P_PARAM_CUSTOM_RFTEST_RX_STATUS_STRUC_T; + +typedef union _EVENT_TEST_STATUS { + PARAM_MTK_WIFI_TEST_STRUC_T rATInfo; +// PARAM_CUSTOM_RFTEST_TX_STATUS_STRUC_T rTxStatus; +// PARAM_CUSTOM_RFTEST_RX_STATUS_STRUC_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_STRUC_T { + UINT_32 u4NoaDurationMs; + UINT_32 u4NoaIntervalMs; + UINT_32 u4NoaCount; +} CMD_CUSTOM_NOA_PARAM_STRUC_T, *P_CMD_CUSTOM_NOA_PARAM_STRUC_T; + +typedef struct _CMD_CUSTOM_OPPPS_PARAM_STRUC_T { + UINT_32 u4CTwindowMs; +} CMD_CUSTOM_OPPPS_PARAM_STRUC_T, *P_CMD_CUSTOM_OPPPS_PARAM_STRUC_T; + +typedef struct _CMD_CUSTOM_UAPSD_PARAM_STRUC_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_STRUC_T, *P_CMD_CUSTOM_UAPSD_PARAM_STRUC_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; + UINT_8 aucReserved[2]; +} 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; + +#if CFG_SUPPORT_OSC_SETTING && defined(MT5931) +typedef struct _CMD_MCU_LP_PARAM_T { + UINT_16 u2OscStableTime; + UINT_8 ucReserved[6]; +} CMD_MCU_LP_PARAM_T, *P_CMD_MCU_LP_PARAM_T; +#endif + + +// 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; + +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 u2Reserved; + 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; + +// 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 aucRsv[1]; + 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_STRUC_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_STRUC_T, *P_CMD_SET_WMM_PS_TEST_STRUC_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_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_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 extention. */ + 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; + +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(MT5931) || 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 _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 struct _EVENT_BSS_BEACON_TIMEOUT_T { + UINT_8 ucNetTypeIndex; + UINT_8 aucReserved[3]; +} 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_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 _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; + +/******************************************************************************* +* P U B 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 +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 + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _NIC_CMD_EVENT_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic_init_cmd_event.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic_init_cmd_event.h new file mode 100755 index 000000000000..84ed48cf14fc --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/nic_init_cmd_event.h @@ -0,0 +1,225 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic_init_cmd_event.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/p2p_typedef.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/p2p_typedef.h new file mode 100755 index 000000000000..ad798890b8cf --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/p2p_typedef.h @@ -0,0 +1,310 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/p2p_typedef.h#4 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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 (*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/mtk_wcn_combo/drv_wlan/wlan/include/precomp.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/precomp.h new file mode 100755 index 000000000000..9c2534b4f281 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/precomp.h @@ -0,0 +1,385 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/precomp.h#1 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: precomp.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 04 18 2011 terry.wu + * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED + * Remove flag CFG_WIFI_DIRECT_MOVED. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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" + +#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" +#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 "hal.h" + +#if defined(MT6620) + #include "mt6620_reg.h" +#elif defined(MT5931) + #include "mt5931_reg.h" +#elif defined(MT6628) + #include "mt6628_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 "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" + +/******************************************************************************* +* 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/mtk_wcn_combo/drv_wlan/wlan/include/pwr_mgt.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/pwr_mgt.h new file mode 100755 index 000000000000..288589b2f40f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/pwr_mgt.h @@ -0,0 +1,191 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: pwr_mgt.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 adress & 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/mtk_wcn_combo/drv_wlan/wlan/include/queue.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/queue.h new file mode 100755 index 000000000000..aee2ccd34757 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/queue.h @@ -0,0 +1,233 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: queue.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +******************************************************************************** +*/ +#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) \ + { \ + ASSERT(prQueue); \ + 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) \ + { \ + ASSERT(prQueue); \ + 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) \ + { \ + 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) \ + { \ + ASSERT(prDestQueue); \ + ASSERT(prSrcQueue); \ + *(P_QUE_T)prDestQueue = *(P_QUE_T)prSrcQueue; \ + QUEUE_INITIALIZE(prSrcQueue); \ + } + +#define QUEUE_CONCATENATE_QUEUES(prDestQueue, prSrcQueue) \ + { \ + ASSERT(prDestQueue); \ + 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/mtk_wcn_combo/drv_wlan/wlan/include/rftest.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/rftest.h new file mode 100755 index 000000000000..5cb7c3201445 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/rftest.h @@ -0,0 +1,361 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/rftest.h#1 $ +*/ + +/*! \file "rftest.h" + \brief definitions for RF Productino test + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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 + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/include/typedef.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/typedef.h new file mode 100755 index 000000000000..6d9ed672bffb --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/typedef.h @@ -0,0 +1,281 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: typedef.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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_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) + +/* 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 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/mtk_wcn_combo/drv_wlan/wlan/include/wlan_bow.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_bow.h new file mode 100755 index 000000000000..93fe2c83bb1a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_bow.h @@ -0,0 +1,591 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +/******************************************************************************* +* 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, + UINT_32 u4Param + ); + +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 UINT_32 u4Param + ); + +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/mtk_wcn_combo/drv_wlan/wlan/include/wlan_lib.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_lib.h new file mode 100755 index 000000000000..40da9ddb3014 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_lib.h @@ -0,0 +1,987 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/wlan_lib.h#2 $ +*/ + +/*! \file "wlan_lib.h" + \brief The declaration of the functions of the wlanAdpater objects + + Detail description. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: wlan_lib.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. + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 while tearing down a station connection. + * + * 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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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" + +/******************************************************************************* +* 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 + +/******************************************************************************* +* 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; + +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; + // 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; + +/******************************************************************************* +* P U B 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 + ); + +BOOL +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 UINT_32 u4Data + ); + +VOID +wlanReleasePendingCMDbyNetwork( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetworkType + ); + +VOID +wlanReturnPacket ( + IN P_ADAPTER_T prAdapter, + IN PVOID pvPacket + ); + +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 Retreive by Polling */ +/*----------------------------------------------------------------------------*/ +WLAN_STATUS +wlanQueryPermanentAddress( + IN P_ADAPTER_T prAdapter + ); + + +/*----------------------------------------------------------------------------*/ +/* NIC Capability Retrieve by Polling */ +/*----------------------------------------------------------------------------*/ +WLAN_STATUS +wlanQueryNicCapability( + IN P_ADAPTER_T prAdapter + ); + + +/*----------------------------------------------------------------------------*/ +/* 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 + ); + +#if CFG_SUPPORT_OSC_SETTING && defined(MT5931) +WLAN_STATUS +wlanSetMcuOscStableTime ( + IN P_ADAPTER_T prAdapter, + IN UINT_16 u2OscStableTime + ); +#endif + +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 + ); + +#endif /* _WLAN_LIB_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_oid.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_oid.h new file mode 100755 index 000000000000..88cc92d27f8b --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/include/wlan_oid.h @@ -0,0 +1,2058 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/include/wlan_oid.h#4 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: wlan_oid.h $ + * + * 01 19 2012 yuche.tsai + * NULL + * Fix RX filter issue for P2P network. + * + * 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. + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 22 2011 george.huang + * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command + * link with supplicant commands + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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 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]; +} PARAM_SSID_T, *P_PARAM_SSID_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[1]; /*!< 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[1]; /*!< 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, + 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_STRUC_T { + UINT_32 u4McrOffset; + UINT_32 u4McrData; +} PARAM_CUSTOM_MCR_RW_STRUC_T, *P_PARAM_CUSTOM_MCR_RW_STRUC_T; + + +typedef struct _PARAM_CUSTOM_SW_CTRL_STRUC_T { + UINT_32 u4Id; + UINT_32 u4Data; +} PARAM_CUSTOM_SW_CTRL_STRUC_T, *P_PARAM_CUSTOM_SW_CTRL_STRUC_T; + + +typedef struct _PARAM_CUSTOM_EEPROM_RW_STRUC_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_STRUC_T, *P_PARAM_CUSTOM_EEPROM_RW_STRUC_T, + PARAM_CUSTOM_NVRAM_RW_STRUCT_T, *P_PARAM_CUSTOM_NVRAM_RW_STRUCT_T; + +typedef struct _PARAM_CUSTOM_WMM_PS_TEST_STRUC_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_STRUC_T, *P_PARAM_CUSTOM_WMM_PS_TEST_STRUC_T; + +typedef struct _PARAM_CUSTOM_NOA_PARAM_STRUC_T { + UINT_32 u4NoaDurationMs; + UINT_32 u4NoaIntervalMs; + UINT_32 u4NoaCount; +} PARAM_CUSTOM_NOA_PARAM_STRUC_T, *P_PARAM_CUSTOM_NOA_PARAM_STRUC_T; + +typedef struct _PARAM_CUSTOM_OPPPS_PARAM_STRUC_T { + UINT_32 u4CTwindowMs; +} PARAM_CUSTOM_OPPPS_PARAM_STRUC_T, *P_PARAM_CUSTOM_OPPPS_PARAM_STRUC_T; + +typedef struct _PARAM_CUSTOM_UAPSD_PARAM_STRUC_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_STRUC_T, *P_PARAM_CUSTOM_UAPSD_PARAM_STRUC_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_STRUC_T { + UINT_32 u4FuncIndex; + UINT_32 u4FuncData; +} PARAM_MTK_WIFI_TEST_STRUC_T, *P_PARAM_MTK_WIFI_TEST_STRUC_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_STRUC_T { + ENUM_MTK_LP_TEST_MODE_T rLpTestMode; + UINT_32 u4BcnRcvNum; +} PARAM_MTK_SLT_LP_TEST_STRUC_T, *P_PARAM_MTK_SLT_LP_TEST_STRUC_T; + +typedef struct _PARAM_MTK_SLT_TR_TEST_STRUC_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_STRUC_T, *P_PARAM_MTK_SLT_TR_TEST_STRUC_T; + +typedef struct _PARAM_MTK_SLT_INITIAL_STRUC_T { + UINT_8 aucTargetMacAddr[PARAM_MAC_ADDR_LEN]; + UINT_16 u2SiteID; +} PARAM_MTK_SLT_INITIAL_STRUC_T, *P_PARAM_MTK_SLT_INITIAL_STRUC_T; + +typedef struct _PARAM_MTK_SLT_TEST_STRUC_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_STRUC_T rMtkInitTest; + PARAM_MTK_SLT_LP_TEST_STRUC_T rMtkLpTest; + PARAM_MTK_SLT_TR_TEST_STRUC_T rMtkTRTest; + } unFuncInfoContent; + +} PARAM_MTK_SLT_TEST_STRUC_T, *P_PARAM_MTK_SLT_TEST_STRUC_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; + +/******************************************************************************* +* P U B 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 +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 +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, + 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 +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 + ); + +#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 +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 + ); + + +#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 + ); + +/* +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 + ); +*/ +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _WLAN_OID_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/aaa_fsm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/aaa_fsm.c new file mode 100755 index 000000000000..2fde7696f74f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/aaa_fsm.c @@ -0,0 +1,1552 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/aaa_fsm.c#1 $ +*/ + +/*! \file "aaa_fsm.c" + \brief This file defines the FSM for AAA MODULE. + + This file defines the FSM for AAA MODULE. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: aaa_fsm.c $ + * + * 02 22 2012 yuche.tsai + * [ALPS00240483] [Wifi P2P]Run Sigma tool of A69. Always run fail on 5.1.2. No get correct connection from Realtek. + * Fix assoc response without P2P IE issue for Sigma test. + * + * 12 02 2011 yuche.tsai + * NULL + * Resolve class 3 error issue under AP mode. + * + * data frame may TX before Assoc Response TX. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 06 29 2011 terry.wu + * NULL + * Add BoW 11n support. + * + * 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 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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); + + return; +} /* 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) { + + if(prAdapter->rP2pFuncLkr.prP2pValidateAuth) { + //4 <1.2> Validate Auth Frame for Network Specific Conditions + fgReplyAuth = + prAdapter->rP2pFuncLkr.prP2pValidateAuth( + prAdapter, + prSwRfb, + &prStaRec, + &u2StatusCode); + } + else { + ASSERT(0); + } + } + 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); + + } + + return; +} /* 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, WARN, ("Previous AuthAssocState (%d) != SEND_AUTH2.\n", + prStaRec->eAuthAssocState)); + 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) { + if(prAdapter->rP2pFuncLkr.prP2pValidateAssocReq) { + //4 <2.2> Validate Assoc Req Frame for Network Specific Conditions + fgReplyAssocResp = prAdapter->rP2pFuncLkr.prP2pValidateAssocReq( + prAdapter, + prSwRfb, + (PUINT_16)&u2StatusCode); + } + else { + ASSERT(0); + } + } + 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_RSP) { + + 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))) { + ASSERT(prAdapter->rP2pFuncLkr.prP2pRunEventAAAComplete); + if (prAdapter->rP2pFuncLkr.prP2pRunEventAAAComplete(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 Assocation ID */ + + /* If (Re)association fail, the peer can try Assocation 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 Assocation ID */ + + /* If (Re)association fail, the peer can try Assocation 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 Assocation ID */ + + /* If (Re)association fail, the peer can try Assocation 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 = %ld\n", kalGetTimeTick())); + + prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex); + + if ((!prStaRec) || (!prStaRec->fgIsInUse)) { + 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]); + + 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))) { + if(prAdapter->rP2pFuncLkr.prP2pRunEventAAATxFail) { + prAdapter->rP2pFuncLkr.prP2pRunEventAAATxFail(prAdapter, prStaRec); + } else { + ASSERT(0); + } + } +#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))) { + if(prAdapter->rP2pFuncLkr.prP2pRunEventAAASuccess) { + prAdapter->rP2pFuncLkr.prP2pRunEventAAASuccess(prAdapter, prStaRec); + } else { + ASSERT(0); + } + } +#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))) { + if(prAdapter->rP2pFuncLkr.prP2pRunEventAAATxFail) { + prAdapter->rP2pFuncLkr.prP2pRunEventAAATxFail(prAdapter, prStaRec); + } else { + ASSERT(0); + } + } +#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) { + + /* Update Station Record - Class 1 Flag */ + prStaRec->ucStaState = STA_STATE_1; + } +#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); + } + + return; +} /* 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; + + return; +} /* 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); + return; +} /* 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: ["MACSTR"]\n", MAC2STR(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 Infomation + if (prAdapter->fgIsEnableWMM && + (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { + + prBssInfo->fgIsWmmAssoc = TRUE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC3; + + qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); + + if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, + sizeof(WMM_INFO_T)); + } + else { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, + sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); + } + } + else { + prBssInfo->fgIsWmmAssoc = FALSE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC1; + + kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); + } + + + //4 <3.C> Operational Rate Set & BSS Basic Rate Set + prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; + prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; + + + //4 <3.D> Short Preamble + if (prBssInfo->fgIsERPPresent) { + + /* NOTE(Kevin 2007/12/24): Truth Table. + * Short Preamble Bit in + * Final Driver Setting(Short) + * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) + * TRUE FALSE TRUE FALSE + * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) + * FALSE FALSE TRUE FALSE + * TRUE TRUE FALSE TRUE(follow ERP) + * TRUE TRUE TRUE FALSE(follow ERP) + * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) + * FALSE TRUE TRUE FALSE(we should set to FALSE) + */ + if ((prPeerBssInfo->fgIsShortPreambleAllowed) && + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && + (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { + + prBssInfo->fgIsShortPreambleAllowed = TRUE; + + if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) { + prBssInfo->fgUseShortPreamble = FALSE; + } + else { + prBssInfo->fgUseShortPreamble = TRUE; + } + } + else { + prBssInfo->fgIsShortPreambleAllowed = FALSE; + prBssInfo->fgUseShortPreamble = FALSE; + } + } + else { + /* NOTE(Kevin 2007/12/24): Truth Table. + * Short Preamble Bit in + * Final Driver Setting(Short) + * TRUE FALSE FALSE + * FALSE FALSE FALSE + * TRUE TRUE TRUE + * FALSE TRUE(status success) TRUE + * --> Honor the result of prPeerBssInfo. + */ + + prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = + prPeerBssInfo->fgIsShortPreambleAllowed; + } + + DBGLOG(JOIN, INFO, ("prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", + prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble)); + + + //4 <3.E> Short Slot Time + prBssInfo->fgUseShortSlotTime = + prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ + + DBGLOG(JOIN, INFO, ("prBssInfo->fgUseShortSlotTime = %d\n", + prBssInfo->fgUseShortSlotTime)); + + nicSetSlotTime(prAdapter, + prBssInfo->ePhyType, + ((prConnSettings->fgIsShortSlotTimeOptionEnable && + prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); + + + //4 <3.F> Update Tx Rate for Control Frame + bssUpdateTxRateForControlFrame(prAdapter); + + + //4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). + //if (prAdapter->fgIsEnableRoaming) /* NOTE(Kevin): Always prepare info for roaming */ + { + + if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) { + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; + } + else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) { + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; + } + + prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; + + + /* Set the stable time of the associated BSS. We won't do roaming decision + * during the stable time. + */ + SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, + SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); + } + + + //4 <3.H> Update Parameter for TX Fragmentation Threshold +#if CFG_TX_FRAGMENT + txFragInfoUpdate(prAdapter); +#endif /* CFG_TX_FRAGMENT */ + + +//4 <4> Update STA_RECORD_T + /* Get a Station Record if possible */ + prStaRec = staRecGetStaRecordByAddr(prAdapter, + prBssDesc->aucBSSID); + + if (prStaRec) { + UINT_16 u2OperationalRateSet, u2DesiredRateSet; + + //4 <4.A> Desired Rate Set + u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & + prBssInfo->u2OperationalRateSet); + + u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); + if (u2DesiredRateSet) { + prStaRec->u2DesiredRateSet = u2DesiredRateSet; + } + else { + /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ + prStaRec->u2DesiredRateSet = u2OperationalRateSet; + } + + /* Try to set the best initial rate for this entry */ + if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, + prStaRec->rRcpi, + &prStaRec->ucCurrRate1Index)) { + + if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, + &prStaRec->ucCurrRate1Index)) { + ASSERT(0); + } + } + + DBGLOG(JOIN, INFO, ("prStaRec->ucCurrRate1Index = %d\n", + prStaRec->ucCurrRate1Index)); + + //4 <4.B> Preamble Mode + prStaRec->fgIsShortPreambleOptionEnable = + prBssInfo->fgUseShortPreamble; + + //4 <4.C> QoS Flag + prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; + } +#if DBG + else { + ASSERT(0); + } +#endif /* DBG */ + + +//4 <5> Update NIC + //4 <5.A> Update BSSID & Operation Mode + nicSetupBSS(prAdapter, prBssInfo); + + //4 <5.B> Update WLAN Table. + if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) { + ASSERT(FALSE); + } + + //4 <5.C> Update Desired Rate Set for BT. +#if CFG_TX_FRAGMENT + if (prConnSettings->fgIsEnableTxAutoFragmentForBT) { + txRateSetInitForBT(prAdapter, prStaRec); + } +#endif /* CFG_TX_FRAGMENT */ + + //4 <5.D> TX AC Parameter and TX/RX Queue Control + if (prBssInfo->fgIsWmmAssoc) { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, FALSE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); + } + else { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, TRUE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); + + nicTxNonQoSUpdateTXQParameters(prAdapter, + prBssInfo->ePhyType); + } + +#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN + { + prTxCtrl->fgBlockTxDuringJoin = FALSE; + + #if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ + nicTxFlushStopQueues(prAdapter, (UINT_8)TXQ_DATA_MASK, (UINT_8)NULL); + #endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxRetransmitOfSendWaitQue(prAdapter); + + if (prTxCtrl->fgIsPacketInOsSendQueue) { + nicTxRetransmitOfOsSendQue(prAdapter); + } + + #if CFG_SDIO_TX_ENHANCE + halTxLeftClusteredMpdu(prAdapter); + #endif /* CFG_SDIO_TX_ENHANCE */ + + } +#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ + + +//4 <6> Setup CONNECTION flag. + prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; + prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; + + if (prJoinInfo->fgIsReAssoc) { + prAdapter->fgBypassPortCtrlForRoaming = TRUE; + } + else { + prAdapter->fgBypassPortCtrlForRoaming = FALSE; + } + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_CONNECT, + (PVOID)NULL, + 0); + + return; +} /* end of joinComplete() */ +#endif + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/ais_fsm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/ais_fsm.c new file mode 100755 index 000000000000..503d9fe072f0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/ais_fsm.c @@ -0,0 +1,4582 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/ais_fsm.c#2 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: ais_fsm.c $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 + * Add XLOG related code and define. + * + * 10 26 2011 tsaiyuan.hsu + * [WCXRP00001064] [MT6620 Wi-Fi][DRV]] add code with roaming awareness when disconnecting AIS network + * be aware of 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 + * . + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 + * follow-ups for frequency-shifted WAPI AP support + * + * 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. + * + * 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 + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 occured 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 occured + * + * 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 Microsoft 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 infomation 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 seperate 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 + +/******************************************************************************* +* 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") +}; +/*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; + + prConnSettings = &(prAdapter->rWifiVar.rConnSettings); + + /* Setup default values for operation */ + COPY_MAC_ADDR(prConnSettings->aucMacAddress, aucZeroMacAddr); + + prConnSettings->ucDelayTimeOfDisconnectEvent = AIS_DELAY_TIME_OF_DISCONNECT_SEC; + + COPY_MAC_ADDR(prConnSettings->aucBSSID, aucAnyBSSID); + prConnSettings->fgIsConnByBssidIssued = FALSE; + + prConnSettings->fgIsConnReqIssued = 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; + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +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, INFO, ("->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, + (UINT_32)NULL); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rIbssAloneTimer, + (PFN_MGMT_TIMEOUT_FUNC)aisFsmRunEventIbssAloneTimeOut, + (UINT_32)NULL); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rIndicationOfDisconnectTimer, + (PFN_MGMT_TIMEOUT_FUNC)aisPostponedEventOfDisconnTimeout, + (UINT_32)NULL); + + cnmTimerInitTimer(prAdapter, + &prAisFsmInfo->rJoinTimeoutTimer, + (PFN_MGMT_TIMEOUT_FUNC)aisFsmRunEventJoinTimeout, + (UINT_32)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); + + return; +} /* 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); + + //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 + + return; +} /* 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); + + prAisFsmInfo->prTargetStaRec = prStaRec; + + //4 <2.1> sync. to firmware domain + 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 (prConnSettings->eConnectionPolicy == CONNECT_BY_SSID_ANY) { + + 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); + + return; +} /* 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); + + return; +} /* 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); + + 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); + + return; +} /* 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; + + return; +} /* 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); + + return; +} /* 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); + + /* 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; + + return; +} /* 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); + + return; +} +#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; + + BOOLEAN fgIsTransition = (BOOLEAN)FALSE; + + DEBUGFUNC("aisFsmSteps()"); + + prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); + prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); + prConnSettings = &(prAdapter->rWifiVar.rConnSettings); + + do { + + /* Do entering Next State */ + prAisFsmInfo->ePreviousState = prAisFsmInfo->eCurrentState; + +#if CFG_SUPPORT_XLOG + DBGLOG(AIS, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n", + DBG_AIS_IDX, + prAisFsmInfo->eCurrentState, + eNextState)); +#else + DBGLOG(AIS, STATE, ("TRANSITION: [%s] -> [%s]\n", + apucDebugAisState[prAisFsmInfo->eCurrentState], + apucDebugAisState[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); + + if(prAisReq == NULL || prAisReq->eReqType == AIS_REQUEST_RECONNECT) { + if (prConnSettings->fgIsConnReqIssued) { + + 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) { + if(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); + } + + 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 + + // we are under Roaming Condition. + if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { + if(prAisFsmInfo->ucConnTrialCount > AIS_ROAMING_CONNECTION_TRIAL_LIMIT) { +#if CFG_SUPPORT_ROAMING + roamingFsmRunEventFail(prAdapter, ROAMING_FAIL_REASON_CONNLIMIT); +#endif /* CFG_SUPPORT_ROAMING */ + // reset retry count + prAisFsmInfo->ucConnTrialCount = 0; + + // abort connection trial + prConnSettings->fgIsConnReqIssued = FALSE; + + eNextState = AIS_STATE_NORMAL_TR; + fgIsTransition = TRUE; + + break; + } + } + + //4 <2> We are not under Roaming Condition. + if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) { + + //4 <2.a> If we have the matched one + if (prBssDesc) { + + //4 Stored the Selected BSS security cipher. For later asoc req compose IE + prAisBssInfo->u4RsnSelectedGroupCipher = + prBssDesc->u4RsnSelectedGroupCipher; + prAisBssInfo->u4RsnSelectedPairwiseCipher = + prBssDesc->u4RsnSelectedPairwiseCipher; + prAisBssInfo->u4RsnSelectedAKMSuite = + prBssDesc->u4RsnSelectedAKMSuite; + + //4 Do STATE transition and update current Operation Mode. + if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) { + + prAisBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE; + + /* Record the target BSS_DESC_T for next STATE. */ + prAisFsmInfo->prTargetBssDesc = prBssDesc; + + /* Transit to channel acquire */ + eNextState = AIS_STATE_REQ_CHANNEL_JOIN; + fgIsTransition = TRUE; + + // increase connection trial count + prAisFsmInfo->ucConnTrialCount++; + } +#if CFG_SUPPORT_ADHOC + else if (prBssDesc->eBSSType == BSS_TYPE_IBSS) { + + prAisBssInfo->eCurrentOPMode = OP_MODE_IBSS; + + /* Record the target BSS_DESC_T for next STATE. */ + prAisFsmInfo->prTargetBssDesc = prBssDesc; + + eNextState = AIS_STATE_IBSS_MERGE; + fgIsTransition = TRUE; + } +#endif /* CFG_SUPPORT_ADHOC */ + else { + ASSERT(0); + eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; + fgIsTransition = TRUE; + } + } + //4 <2.b> If we don't have the matched one + else { + + // increase connection trial count for infrastructure connection + if (prConnSettings->eOPMode == NET_TYPE_INFRA) { + prAisFsmInfo->ucConnTrialCount++; + } + + //4 Try to SCAN + if (prAisFsmInfo->fgTryScan) { + eNextState = AIS_STATE_LOOKING_FOR; + + fgIsTransition = TRUE; + } + //4 We've do SCAN already, now wait in some STATE. + else { + 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. + */ + if ((!prBssDesc) || /* CASE I */ + (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE) || /* CASE II */ + (prBssDesc->fgIsConnected) /* CASE III */) { +#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; + } + //4 <3.b> Try to roam out for JOIN this BSS_DESC_T. + else { +#if DBG + ASSERT(UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)); +#endif /* DBG */ + + //4 Record the target BSS_DESC_T for next STATE. + prAisFsmInfo->prTargetBssDesc = prBssDesc; + + // tyhsu: increase connection trial count + prAisFsmInfo->ucConnTrialCount++; + + /* Transit to channel acquire */ + eNextState = AIS_STATE_REQ_CHANNEL_JOIN; + fgIsTransition = TRUE; + } + } + + break; + + case AIS_STATE_WAIT_FOR_NEXT_SCAN: + + DBGLOG(AIS, LOUD, ("SCAN: Idle Begin - Current Time = %ld\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 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(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(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 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); + + prAisFsmInfo->fgTryScan = FALSE; /* Will enable background sleep for infrastructure */ + + 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; + 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; + } + } + + 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); + break; + + default: + ASSERT(0); /* Make sure we have handle all STATEs */ + break; + + } + } + while (fgIsTransition); + + return; + +} /* end of aisFsmSteps() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + + DBGLOG(AIS, LOUD, ("EVENT-SCAN DONE: Current Time = %ld\n", kalGetTimeTick())); + + 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.\n")); + } + else { + switch (prAisFsmInfo->eCurrentState) { + case AIS_STATE_SCAN: + prConnSettings->fgIsScanReqIssued = FALSE; + + kalScanDone(prAdapter->prGlueInfo, KAL_NETWORK_TYPE_AIS_INDEX, WLAN_STATUS_SUCCESS); + eNextState = AIS_STATE_IDLE; + break; + + case AIS_STATE_ONLINE_SCAN: + prConnSettings->fgIsScanReqIssued = FALSE; + + 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 */ + break; + + case AIS_STATE_LOOKING_FOR: +#if CFG_SUPPORT_ROAMING + eNextState = aisFsmRoamingScanResultsUpdate(prAdapter); +#else + eNextState = AIS_STATE_SEARCH; +#endif /* CFG_SUPPORT_ROAMING */ + break; + + default: + break; + + } + } + + if (eNextState != prAisFsmInfo->eCurrentState) { + aisFsmSteps(prAdapter, eNextState); + } + + return; +} /* 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; + + DEBUGFUNC("aisFsmRunEventAbort()"); + + ASSERT(prAdapter); + ASSERT(prMsgHdr); + prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); + + //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 CFG_SUPPORT_XLOG + DBGLOG(AIS, LOUD, ("[%d] EVENT-ABORT: Current State [%d]\n", + DBG_AIS_IDX, + prAisFsmInfo->eCurrentState)); +#else + DBGLOG(AIS, LOUD, ("EVENT-ABORT: Current State %s\n", + apucDebugAisState[prAisFsmInfo->eCurrentState])); +#endif + + //4 <2> clear previous pending connection request and insert new one + 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); + } + + return; +} /* 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; + + 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; + } + else { + /* Do abort NORMAL_TR */ + aisFsmStateAbort_NORMAL_TR(prAdapter); + } + } + + aisFsmDisconnect(prAdapter, fgDelayIndication); + + return; + +} /* 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; + BOOLEAN fgReassociated = FALSE; + + DEBUGFUNC("aisFsmRunEventJoinComplete()"); + + ASSERT(prMsgHdr); + + prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); + prJoinCompMsg = (P_MSG_JOIN_COMP_T)prMsgHdr; + prStaRec = prJoinCompMsg->prStaRec; + prAssocRspSwRfb = prJoinCompMsg->prSwRfb; + + eNextState = prAisFsmInfo->eCurrentState; + + // Check State and SEQ NUM + if (prAisFsmInfo->eCurrentState == AIS_STATE_JOIN) { + P_BSS_INFO_T prAisBssInfo; + + 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.2.1> check for non-roaming/reassociated + if(EQUAL_MAC_ADDR(prAisBssInfo->aucBSSID, ((P_WLAN_ASSOC_RSP_FRAME_T)prAssocRspSwRfb->pvHeader)->aucBSSID) && + prAisBssInfo->eConnectionStateIndicated == PARAM_MEDIA_STATE_CONNECTED) { + fgReassociated = TRUE; + } + + //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); + +#if defined(LINUX) + //4 Android Framework needs DISCONNECT indication for non-roaming/reassociated cases + if(fgReassociated) { + aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE); + } +#endif + //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); + } + +#if CFG_SUPPORT_ROAMING + 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); + + ASSERT(prBssDesc); + ASSERT(prBssDesc->fgIsConnecting); + + if(prBssDesc) { + prBssDesc->fgIsConnecting = FALSE; + } + + if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) { +#if CFG_SUPPORT_ROAMING + eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; +#endif /* CFG_SUPPORT_ROAMING */ + } + else { + /* 4. 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); + } + + if (prAssocRspSwRfb) { + nicRxReturnRFB(prAdapter, prAssocRspSwRfb); + } + + cnmMemFree(prAdapter, prMsgHdr); + + return; +} /* 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); + + return; +} /* 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. + if ((prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID)) != 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); + + return; +} /* 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. + if ((prBssDesc = scanSearchBssDescByTA(prAdapter, prStaRec->aucMacAddr)) != 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. + if ((prBssDesc = scanSearchBssDescByBssid(prAdapter, prAisBssInfo->aucBSSID)) != 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); + } + + return; +} /* 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)); + } + + return; +} /* 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, + UINT_32 u4Param + ) +{ + P_BSS_INFO_T prAisBssInfo; + + prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); + + //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); + + //4 <3> Indicate Disconnected Event to Host immediately. + aisIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, FALSE); + + return; +} /* 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, INFO, ("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; + } + + //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; + + //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 + + return; +} /* 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) { + + prAisBssInfo->ucPhyTypeSet = + prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN; /* Depend on eBand */ + + prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + } + else { + + prAisBssInfo->ucPhyTypeSet = + prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN; /* Depend on eBand */ + + prAisBssInfo->ucConfigAdHocAPMode = AD_HOC_MODE_11A; /* Depend on eCurrentOPMode and ucPhyTypeSet */ + } + + //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; + + return; +} /* 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)((UINT_32)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) { + + 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) { + 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. + 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); + + return; +} /* end of aisFsmDisconnect() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* @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, + UINT_32 u4Param + ) +{ + 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 = %ld\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); + } + + return; +} /* 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, + UINT_32 u4Param + ) +{ + 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); + } + + return; +} /* 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, + UINT_32 u4Param + ) +{ + P_AIS_FSM_INFO_T prAisFsmInfo; + ENUM_AIS_STATE_T eNextState; + + DEBUGFUNC("aisFsmRunEventJoinTimeout()"); + + prAisFsmInfo = &(prAdapter->rWifiVar.rAisFsmInfo); + eNextState = prAisFsmInfo->eCurrentState; + + 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->prTargetStaRec->ucJoinFailureCount++; + + if(prAisFsmInfo->prTargetStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) { + /* 3.1 Retreat to AIS_STATE_SEARCH state for next try */ + eNextState = AIS_STATE_SEARCH; + } + else { + /* 3.2 Retreat to AIS_STATE_WAIT_FOR_NEXT_SCAN state for next try */ + eNextState = AIS_STATE_WAIT_FOR_NEXT_SCAN; + } + 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); + } + + return; +} /* end of aisFsmRunEventJoinTimeout() */ + + +#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); + + return; +} +#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] prAdapter Pointer of SSID_T if specified +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +VOID +aisFsmScanRequest ( + IN P_ADAPTER_T prAdapter, + IN P_PARAM_SSID_T prSsid + ) +{ + P_CONNECTION_SETTINGS_T prConnSettings; + P_BSS_INFO_T prAisBssInfo; + P_AIS_FSM_INFO_T prAisFsmInfo; + + DEBUGFUNC("aisFsmScanRequest()"); + + ASSERT(prAdapter); + + 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(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)); + } + + return; +} /* 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 { /* mismatched grant */ + /* 2. return channel privilege to CNM immediately */ + aisFsmReleaseCh(prAdapter); + } + + return; +} /* 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); + } + + return; +} /* 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) { + aisFsmStateAbort(prAdapter, DISCONNECT_REASON_CODE_RADIO_LOST, TRUE); + } + + return; +} /* end of aisBssBeaconTimeout() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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(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; + + /* 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); + } + + return; +} /* 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 */ + + return; +} /* 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); + + return; +} /* 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); + } + + return; +} + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/assoc.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/assoc.c new file mode 100755 index 000000000000..35c39f1a2ecb --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/assoc.c @@ -0,0 +1,2087 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/assoc.c#3 $ +*/ + +/*! \file "assoc.c" + \brief This file includes the association-related functions. + + This file includes the association-related functions. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: assoc.c $ + * + * 02 22 2012 yuche.tsai + * [ALPS00240483] [Wifi P2P]Run Sigma tool of A69. Always run fail on 5.1.2. No get correct connection from Realtek. + * Fix assoc response without P2P IE issue for Sigma test. + * + * 01 17 2012 wh.su + * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting + * Adding the related code which support beacon can reflect the security setting open or WPA2-PSK, WPA-PSK not yet + * Adn support the indicate the assoc request ie at New STA CMD, needed kernel patch. + * + * 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 + * . + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 + * Append P2P IE in assoc request if P2P is enabled. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 recieve a assoc response frame but no p2p fucntion. + * + * 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 Microsoft 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_SUPPORT_WAPI + { (ELEM_HDR_LEN + ELEM_MAX_LEN_WAPI), NULL, wapiGenerateWAPIIE }, /* 68 */ +#endif +#if CFG_RSN_MIGRATION + { (ELEM_HDR_LEN + ELEM_MAX_LEN_WPA), NULL, rsnGenerateWPAIE }, /* 72 */ +#endif + { (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmReqGenerateExtCapIE }, /* 127 */ + { (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_INFO), NULL, mqmGenerateWmmInfoIE }, /* 221 */ +#if CFG_RSN_MIGRATION + { (ELEM_HDR_LEN + ELEM_MAX_LEN_RSN), NULL, rsnGenerateRSNIE }, /* 221 */ +#endif +#if CFG_ENABLE_WIFI_DIRECT + { (0), linkToP2pCalculateP2P_IELenForAssocReq, linkToP2pGenerateP2P_IEForAssocReq }, /* 221 */ +#endif +}; + +#if CFG_SUPPORT_AAA +VERIFY_IE_ENTRY_T rxAssocReqIETable[] = { + { ELEM_ID_RESERVED, NULL } /* 255 */ +}; + + +#if 1 +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, linkToRlmRspGenerateObssScanIE }, /* 74 */ + { (0), linkToP2pCalculateP2P_IELenForAssocRsp, linkToP2pGenerateP2P_IEForAssocRsp }, /* 221 */ +#endif + { (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), NULL, rlmRspGenerateExtCapIE }, /* 127 */ + { (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), NULL, mqmGenerateWmmParamIE } /* 221 */ +}; +#else +APPEND_IE_ENTRY_T txAssocRespIETable[] = { + { (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP), rlmRspGenerateErpIE }, /* 42 */ + { (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP), rlmRspGenerateHtCapIE }, /* 45 */ + { (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP), rlmRspGenerateHtOpIE }, /* 61 */ +#if CFG_ENABLE_WIFI_DIRECT + { (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN), linkToRlmRspGenerateObssScanIE }, /* 74 */ + { (ELEM_HDR_LEN + 4), linkToP2pGenerateP2P_IEForAssocRsp }, /* 221 */ +#endif + { (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP), rlmRspGenerateExtCapIE }, /* 127 */ + { (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM), mqmGenerateWmmParamIE } /* 221 */ +}; +#endif +#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 +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ UINT_16 +assocBuildCapabilityInfo ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prStaRec + ) +{ + UINT_32 u4NonHTPhyType; + UINT_16 u2CapInfo; + + + ASSERT(prStaRec); + + + /* Set up our requested capabilities. */ + u2CapInfo = CAP_INFO_ESS; + u2CapInfo |= CAP_CF_STA_NOT_POLLABLE; + + if (prStaRec->u2CapInfo & CAP_INFO_PRIVACY) { + u2CapInfo |= CAP_INFO_PRIVACY; + } + + + /* 7.3.1.4 */ + if (prStaRec->fgHasBasicPhyType) { + u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType; + + if ( (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortPreambleOptionImplemented) && + ( (prAdapter->rWifiVar.ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ + ((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 (rNonHTPhyAttributes[u4NonHTPhyType].fgIsShortSlotTimeOptionImplemented && + prAdapter->rWifiVar.fgIsShortSlotTimeOptionEnable) { + u2CapInfo |= CAP_INFO_SHORT_SLOT_TIME; + } + } + + DBGLOG(SAA, LOUD, ("ASSOC REQ: Compose Capability = 0x%04x for Target BSS ["MACSTR"].\n", + u2CapInfo, MAC2STR(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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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)((UINT_32)prMsduInfo->prPacket + + (UINT_32)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))) { + ASSERT(prAdapter->rP2pFuncLkr.prP2pBuildReassocReqFrameCommIEs); + pucBuffer = prAdapter->rP2pFuncLkr.prP2pBuildReassocReqFrameCommIEs(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 { + /* 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); + } + } + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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); + } + + return; +} /* 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 + if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { + if ((prAdapter->fgIsP2PRegistered) && (prAdapter->rP2pFuncLkr.prP2pCalculate_IELenForAssocReq)) { + u2EstimatedExtraIELen = prAdapter->rP2pFuncLkr.prP2pCalculate_IELenForAssocReq(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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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 + if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) { + if ((prAdapter->fgIsP2PRegistered) && (prAdapter->rP2pFuncLkr.prP2pGenerate_IEForAssocReq)) { + prAdapter->rP2pFuncLkr.prP2pGenerate_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)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + +#if CFG_RSN_MIGRATION + kalUpdateReAssocReqInfo(prAdapter->prGlueInfo, + (PUINT_8)&prAssocFrame->u2CapInfo, + prMsduInfo->u2FrameLength, + 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)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD); + + if(prAdapter->rP2pFuncLkr.prKalP2pUpdateAssocInfo) { + prAdapter->rP2pFuncLkr.prKalP2pUpdateAssocInfo( + prAdapter->prGlueInfo, + (PUINT_8)&prAssocFrame->u2CapInfo, + prMsduInfo->u2FrameLength, + fgIsReAssoc); + } else { + ASSERT(0); + } + } +#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. + 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)Assocation Resp Frame. + prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prSwRfb->pvHeader; + + //4 <2> Parse the Header of (Re)Assocation 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)Assocation 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 ((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) ^ (u2RxCapInfo & CAP_INFO_PRIVACY)) { + u2RxStatusCode = STATUS_CODE_CAP_NOT_SUPPORTED; + } + } + + 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)((UINT_32)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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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); + + return; +} /* 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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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)((UINT_32)(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 ["MACSTR"]\n", + MAC2STR(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) && + prAdapter->rP2pFuncLkr.prKalP2pGetCipher && + !prAdapter->rP2pFuncLkr.prKalP2pGetCipher(prAdapter->prGlueInfo))/* || + (((prStaRec->u2CapInfo & CAP_INFO_PRIVACY) == 0) && + prAdapter->rP2pFuncLkr.prKalP2pGetCipher && + prAdapter->rP2pFuncLkr.prKalP2pGetCipher(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; + 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) && (prAdapter->rP2pFuncLkr.prP2pParseCheckForP2pInfoElem)) { + UINT_8 ucOuiType = 0; + + prAdapter->rP2pFuncLkr.prP2pParseCheckForP2pInfoElem(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)) { + if (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 (prAdapter->rP2pFuncLkr.prKalP2pGetCipher && + !prAdapter->rP2pFuncLkr.prKalP2pGetCipher(prAdapter->prGlueInfo)) { + u2StatusCode = STATUS_CODE_CIPHER_SUITE_REJECTED; + break; + } + } + else { + prStaRec->rSecInfo.fgAllowOnly1x = FALSE; + if (prAdapter->rP2pFuncLkr.prKalP2pGetCipher && + prAdapter->rP2pFuncLkr.prKalP2pGetCipher(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; + 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 = kalMemAlloc(u2IELength, VIR_MEM_TYPE); + kalMemCopy(prStaRec->pucAssocReqIe, cp, u2IELength); + } + } + #endif + if(prAdapter->rP2pFuncLkr.prKalP2pUpdateAssocInfo) { + prAdapter->rP2pFuncLkr.prKalP2pUpdateAssocInfo(prAdapter->prGlueInfo, (PUINT_8)&prAssocReqFrame->u2CapInfo, u2IELength + (prStaRec->fgIsReAssoc ? 10 : 4), prStaRec->fgIsReAssoc); + } else { + ASSERT(0); + } + } +#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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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)((UINT_32)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); + } + + return; +} /* 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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); + + return; +} /* 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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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. + nicTxEnqueueMsdu(prAdapter, prMsduInfo); + + return WLAN_STATUS_SUCCESS; + +} /* end of assocSendReAssocRespFrame() */ +#endif /* CFG_SUPPORT_AAA */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/auth.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/auth.c new file mode 100755 index 000000000000..e9388592ba45 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/auth.c @@ -0,0 +1,1398 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/auth.c#1 $ +*/ + +/*! \file "auth.c" + \brief This file includes the authentication-related functions. + + This file includes the authentication-related functions. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: auth.c $ + * + * 11 09 2011 yuche.tsai + * NULL + * Fix Network Index & Station Record Index when TX deauth issue. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * Add feature to send BC deauth frame when under AP/GO mode. + * + * 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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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 + + return; +} /* 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(((UINT_32)(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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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. + 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: + if (prAuthFrame->u2StatusCode != STATUS_CODE_SUCCESSFUL) { + DBGLOG(SAA, WARN, ("Strange Authentication Packet: Auth Trans Seq No = %d, Error Status Code = %d\n", + u2RxTransactionSeqNum, prAuthFrame->u2StatusCode)); + } + else { + ASSERT(0); + } + /* TODO(Kevin): Free SW_RFB_T */ + 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, LOUD, ("Discard Auth frame with auth type = %d, current = %d\n", + u2RxAuthAlgNum, prStaRec->ucAuthAlgNum)); + return WLAN_STATUS_FAILURE; + } + + //WLAN_GET_FIELD_16(&prAuthFrame->u2AuthTransSeqNo, &u2RxTransactionSeqNum); + u2RxTransactionSeqNum = prAuthFrame->u2AuthTransSeqNo; // NOTE(Kevin): Optimized for ARM + if (u2RxTransactionSeqNum != u2TransactionSeqNum) { + DBGLOG(SAA, LOUD, ("Discard Auth frame with Transaction Seq No = %d\n", + u2RxTransactionSeqNum)); + return WLAN_STATUS_FAILURE; + } + + //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; + } + + if ( ( prStaRec->prChallengeText = cnmMemAlloc(prAdapter, RAM_TYPE_MSG, IE_SIZE(prIEHdr)) ) == 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) +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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 + + return; +} /* 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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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 { + return WLAN_STATUS_FAILURE; + } + } + +#endif + + + //4 <6> compose Deauthentication frame header and some fixed fields */ + authComposeDeauthFrameHeaderAndFF( + (PUINT_8)((UINT_32)(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)((UINT_32)(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; + + //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 ["MACSTR"]\n", + MAC2STR(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> 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/mtk_wcn_combo/drv_wlan/wlan/mgmt/bss.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/bss.c new file mode 100755 index 000000000000..aa5c89bcbd53 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/bss.c @@ -0,0 +1,3103 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/bss.c#7 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: bss.c $ + * + * 02 23 2012 yuche.tsai + * [ALPS00240485] [Wifi P2P]Run Sigma tool of A69. Always run fail on 6.1.2 and 6.1.3. sniffer check no framename,proberesp,P2P_IE,0 + * 1. Recompose probe response frame in driver, in order to sync the IEs between supplicant & driver. + * 2. Under GO mode, indicate probe request to supplicant due to WSC IE sync issue. + * Davinci Label: 20120223_ALPS_WIFI_FW_V2_1. + * + * 02 22 2012 yuche.tsai + * [ALPS00240483] [Wifi P2P]Run Sigma tool of A69. Always run fail on 5.1.2. No get correct connection from Realtek. + * Fix assoc response without P2P IE issue for Sigma test. + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 01 28 2012 yuche.tsai + * NULL + * Update for Beacon composing code but not active yet. + * + * 01 20 2012 chinglan.wang + * NULL + * Fix the WPA-PSK TKIP and WPA2-PSK AES security mode bug. + * + * 01 19 2012 chinglan.wang + * NULL + * Support the WPA-PSK TKIP security mode for the tethering.. + * + * 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 + * Fix preamble type of STA 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 + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 07 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 + * Append P2P IE in assoc request if P2P is enabled. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) Chnage 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 occured + * + * 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 + * Seperate 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 Microsoft os query + * adding the wpa-none for ibss beacon. + * + * 04 15 2010 wh.su + * [BORA00000680][MT6620] Support the statistic for Microsoft 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, linkToRlmRspGenerateObssScanIE } /* 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 */ + ,{ 0, linkToP2pCalculateP2P_IELenForBeacon, linkToP2pGenerateP2P_IEForBeacon } /* 221 */ + ,{ 0, linkToP2pCalculateWSC_IELenForBeacon, linkToP2pGenerateWSC_IEForBeacon } /* 221 */ +#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, linkToRlmRspGenerateObssScanIE } /* 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 0 + ,{ 0, linkToP2pCalculateWSC_IELenForProbeRsp, linkToP2pGenerateWSC_IEForProbeRsp } /* 221 */ +#endif /* CFG_ENABLE_WIFI_DIRECT */ + +}; + +#if CFG_ENABLE_WIFI_DIRECT +P_APPEND_VAR_IE_ENTRY_T prTxProbRspIETableWIP2P = NULL; +#endif + +#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->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 (!((prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_ENABLED) || + (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION3_KEY_ABSENT) || + (prAdapter->rWifiVar.rConnSettings.eEncStatus == ENUM_ENCRYPTION_DISABLED))) { + DBGLOG(BSS, INFO, ("Ignore the HT Bit for TKIP as pairwise cipher configed!\n")); + prStaRec->ucPhyTypeSet &= ~PHY_TYPE_BIT_HT; + } + + 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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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)((UINT_32)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); + } + + return; +} /* 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)((UINT_32)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; + 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) { + //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; + 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 = prBssInfo->ucDTIMPeriod; + TIM_IE(pucBuffer)->ucBitmapControl = 0/*ucBitmapControl | (UINT_8)u4N1*/; // will be overwrite by FW + + 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. + */ + } + + + + } + + return; +} /* 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 + + return; +} /* 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(INIT, LOUD, ("bssUpdateBeaconContent\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)((UINT_32)(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 { +#if CFG_ENABLE_WIFI_DIRECT + + if (u4ControlFlags & BSS_PROBE_RESP_INCLUDE_P2P_IE) { + if(prAdapter->fgIsP2PRegistered && prTxProbRspIETableWIP2P) { + ASSERT(prAdapter->rP2pFuncLkr.prP2pGetTxProbRspIETAbleSize); + prIeArray = prTxProbRspIETableWIP2P; + u4IeArraySize = + prAdapter->rP2pFuncLkr.prP2pGetTxProbRspIETAbleSize(); + } else { + DBGLOG(BSS, WARN, ( "prTxProbRspIETableWIP2P is NULL\n")); + ASSERT(0); + } + } + else +#endif /* CFG_ENABLE_WIFI_DIRECT */ + { + 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; + + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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)((UINT_32)(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)) { + + fgReplyProbeResp = prAdapter->rP2pFuncLkr.prP2pFuncValidateProbeReq(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) { + + if (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 */) { + if (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) { + /* 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); + } + + return; +} /* 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["MACSTR"]\n", + MAC2STR(prStaRec->aucMacAddr))); + return; + } + } + } + + LINK_INSERT_TAIL(prStaRecOfClientList, &prStaRec->rLinkEntry); + + return; +} /* 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 (!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; + } + } + } + + DBGLOG(BSS, INFO, ("Current Client List didn't contain that STA_RECORD_T["MACSTR"] before removing.\n", + MAC2STR(prStaRec->aucMacAddr))); + + return; +} /* end of bssRemoveStaRecFromClientList() */ +#endif /* CFG_SUPPORT_ADHOC || CFG_SUPPORT_AAA */ + + +#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: "MACSTR" - Unsupported Phy.\n", + MAC2STR(prBssDesc->aucSrcAddr))); + + break; + } + + if (prBssDesc->fgIsUnknownBssBasicRate) { + DBGLOG(BSS, LOUD, + ("IBSS MERGE: Ignore Peer MAC: "MACSTR" - Unknown Basic Rate.\n", + MAC2STR(prBssDesc->aucSrcAddr))); + + break; + } + + if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { + DBGLOG(BSS, LOUD, + ("IBSS MERGE: Ignore Peer MAC: "MACSTR" - Capability is not matched.\n", + MAC2STR(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: "MACSTR" - Capability is not matched.\n", + MAC2STR(prBssDesc->aucSrcAddr))); + } + + return; + } + + DBGLOG(BSS, LOUD, + ("IBSS MERGE: Peer MAC: "MACSTR" - Check capability was passed.\n", + MAC2STR(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); + + } + + return; +} /* 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]; + + return; +} /* 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 */ + + + return; +} /* 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; + } + } + + return; +} /* 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; + + + pucPartialVirtualBitmap = &prP2pSpecificBssInfo->aucPartialVirtualBitmap[(u2AssocId >> 3)]; // (u2AssocId / 8) + 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; + } + } + } + + return; +} /* end of bssSetTIMBitmap() */ +#endif + +#endif /* CFG_SUPPORT_AAA */ + + +VOID +bssCreateStaRecFromAuth ( + IN P_ADAPTER_T prAdapter + ) +{ + +} + + +VOID +bssUpdateStaRecFromAssocReq ( + IN P_ADAPTER_T prAdapter + ) +{ + +} + +#if CFG_ENABLE_WIFI_DIRECT + +/*link function to p2p module for txBcnIETable*/ +UINT_32 +linkToP2pCalculateP2P_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 || + prAdapter->fgIsP2PRegistered == FALSE) { + return 0; + } + +#if 1 + + if (prAdapter->rP2pFuncLkr.prP2pFuncIsApMode) { + if (prAdapter->rP2pFuncLkr.prP2pFuncIsApMode(prAdapter->rWifiVar.prP2pFsmInfo)) { + return 0; + } + + } + + + if (prAdapter->rP2pFuncLkr.prP2pCalculateP2p_IELenForBeacon) { + return prAdapter->rP2pFuncLkr.prP2pCalculateP2p_IELenForBeacon( + prAdapter, + eNetTypeIndex, + prStaRec + ); + } else { + ASSERT(0); + } +#endif + return 0; +} + +VOID +linkToP2pGenerateP2P_IEForBeacon ( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ) +{ + if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX || + prAdapter->fgIsP2PRegistered == FALSE) { + return; + } +#if 1 + + if (prAdapter->rP2pFuncLkr.prP2pFuncIsApMode) { + if (prAdapter->rP2pFuncLkr.prP2pFuncIsApMode(prAdapter->rWifiVar.prP2pFsmInfo)) { + return; + } + + } + + + if(prAdapter->rP2pFuncLkr.prP2pGenerateP2p_IEForBeacon) { + prAdapter->rP2pFuncLkr.prP2pGenerateP2p_IEForBeacon( + prAdapter, + prMsduInfo + ); + } else { + ASSERT(0); + } +#endif + return; +} + +/*link function to p2p module for txAssocReqIETable*/ +UINT_32 +linkToP2pCalculateP2P_IELenForAssocReq ( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN P_STA_RECORD_T prStaRec + ) +{ + if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX || + prAdapter->fgIsP2PRegistered == FALSE) { + return 0; + } +#if 0 + if(prAdapter->rP2pFuncLkr.prP2pCalculateP2p_IELenForAssocReq) { + return prAdapter->rP2pFuncLkr.prP2pCalculateP2p_IELenForAssocReq( + prAdapter, + eNetTypeIndex, + prStaRec + ); + } else { + ASSERT(0); + } +#endif + return 0; +} /* linkToP2pCalculateP2P_IELenForAssocReq */ + +/*link function to p2p module for txAssocReqIETable*/ +UINT_32 +linkToP2pCalculateP2P_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 || + prAdapter->fgIsP2PRegistered == FALSE) { + return 0; + } +#if 1 + if(prAdapter->rP2pFuncLkr.prP2pCalculateP2p_IELenForAssocRsp) { + return prAdapter->rP2pFuncLkr.prP2pCalculateP2p_IELenForAssocRsp( + prAdapter, + eNetTypeIndex, + prStaRec + ); + } else { + ASSERT(0); + } +#endif + return 0; +} /* linkToP2pCalculateP2P_IELenForAssocRsp */ + + +VOID +linkToP2pGenerateP2P_IEForAssocReq ( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ) +{ + if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX || + prAdapter->fgIsP2PRegistered == FALSE) { + return; + } +#if 0 + if(prAdapter->rP2pFuncLkr.prP2pGenerateP2p_IEForAssocReq) { + prAdapter->rP2pFuncLkr.prP2pGenerateP2p_IEForAssocReq( + prAdapter, + prMsduInfo + ); + } else { + ASSERT(0); + } +#endif + return; +} /* linkToP2pGenerateP2P_IEForAssocReq */ + + +VOID +linkToP2pGenerateP2P_IEForAssocRsp ( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ) +{ + if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX || + prAdapter->fgIsP2PRegistered == FALSE) { + return; + } +#if 1 + if(prAdapter->rP2pFuncLkr.prP2pGenerateP2p_IEForAssocRsp) { + prAdapter->rP2pFuncLkr.prP2pGenerateP2p_IEForAssocRsp( + prAdapter, + prMsduInfo + ); + } else { + ASSERT(0); + } +#endif + return; +} /* linkToP2pGenerateP2P_IEForAssocRsp */ + + +UINT_32 +linkToP2pCalculateWSC_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 || + prAdapter->fgIsP2PRegistered == FALSE) { + return 0; + } +#if 1 + if (prAdapter->rP2pFuncLkr.prP2pCalculateWSC_IELenForBeacon) { + return prAdapter->rP2pFuncLkr.prP2pCalculateWSC_IELenForBeacon( + prAdapter, + eNetTypeIndex, + prStaRec + ); + } + else { + ASSERT(0); + } +#endif + return 0; +} + +VOID +linkToP2pGenerateWSC_IEForBeacon( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ) +{ + if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX || + prAdapter->fgIsP2PRegistered == FALSE) { + return; + } +#if 1 + if (prAdapter->rP2pFuncLkr.prP2pGenerateWSC_IEForBeacon) { + prAdapter->rP2pFuncLkr.prP2pGenerateWSC_IEForBeacon( + prAdapter, + prMsduInfo + ); + } + else { + ASSERT(0); + } +#endif + return; +} + +UINT_32 +linkToP2pCalculateWSC_IELenForProbeRsp ( + IN P_ADAPTER_T prAdapter, + IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex, + IN P_STA_RECORD_T prStaRec + ) +{ + if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX || + prAdapter->fgIsP2PRegistered == FALSE) { + return 0; + } + +#if 0 + if(prAdapter->rP2pFuncLkr.prP2pCalculateWSC_IELenForProbeRsp) { + return prAdapter->rP2pFuncLkr.prP2pCalculateWSC_IELenForProbeRsp( + prAdapter, + eNetTypeIndex, + prStaRec + ); + } else { + ASSERT(0); + } +#endif + return 0; +} + +VOID +linkToP2pGenerateWSC_IEForProbeRsp( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ) +{ + if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX || + prAdapter->fgIsP2PRegistered == FALSE) { + return; + } + + +#if 0 + if(prAdapter->rP2pFuncLkr.prP2pGenerateWSC_IEForProbeRsp) { + prAdapter->rP2pFuncLkr.prP2pGenerateWSC_IEForProbeRsp( + prAdapter, + prMsduInfo + ); + } else { + ASSERT(0); + } +#endif + + return; +} + + +EXPORT_SYMBOL(prTxProbRspIETableWIP2P); + +#endif + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm.c new file mode 100755 index 000000000000..e6e6354846ce --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm.c @@ -0,0 +1,814 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/cnm.c#1 $ +*/ + +/*! \file "cnm.c" + \brief Module of Concurrent Network Management + + Module of Concurrent Network Management +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: cnm.c $ + * + * 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. + * Large Network Type index assert. + * Fix NULL prDev 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 + * . + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 08 17 2011 cm.chang + * [WCXRP00000937] [MT6620 Wi-Fi][Driver][FW] cnm.c line #848 assert when doing monkey test + * Print out net type index for ch request/abourt message + * + * 06 23 2011 cp.wu + * [WCXRP00000798] [MT6620 Wi-Fi][Firmware] Follow-ups for WAPI frequency offset workaround in firmware SCN module + * follow-ups for frequency-shifted WAPI AP support + * + * 06 01 2011 cm.chang + * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function + * Limit AIS channel same with BOW when BOW is active + * + * 04 12 2011 cm.chang + * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency + * . + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 Microsoft 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 + ) +{ + return; +} /* 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 + ) +{ + return; +} /* 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); + + return; +} /* 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); + + return; +} /* 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) && + prAdapter->rP2pFuncLkr.prP2pFuncIsApMode && + prAdapter->rP2pFuncLkr.prP2pFuncIsApMode( + 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; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + + /* 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; + } + } + } + + return TRUE; +} + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_mem.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_mem.c new file mode 100755 index 000000000000..67e1652c5584 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_mem.c @@ -0,0 +1,1339 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: cnm_mem.c $ + * + * 01 17 2012 wh.su + * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting + * Adding the related code which support beacon can reflect the security setting open or WPA2-PSK, WPA-PSK not yet + * Adn support the indicate the assoc request ie at New STA CMD, needed kernel patch. + * + * 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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 DBG + if (prMsduInfo == NULL) { + DBGLOG(MEM, WARN, ("\n")); + DBGLOG(MEM, WARN, ("MgtDesc#=%ld\n", prQueList->u4NumElem)); + +#if CFG_DBG_MGT_BUF + DBGLOG(MEM, WARN, ("rMgtBufInfo: alloc#=%ld, free#=%ld, null#=%ld\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); + 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 +*/ +/*----------------------------------------------------------------------------*/ +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); + + 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; + } + } + +#ifdef LINUX + pvMemory = (PVOID)kalMemAlloc(u4Length, VIR_MEM_TYPE); +#else + pvMemory = (PVOID)NULL; +#endif + +#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; + } + + /* Judge it belongs to which RAM type */ + if ( ((UINT_32)pvMemory >= (UINT_32)&prAdapter->aucMsgBuf[0]) && + ((UINT_32)pvMemory <= (UINT_32)&prAdapter->aucMsgBuf[MSG_BUFFER_SIZE-1])) { + + prBufInfo = &prAdapter->rMsgBufInfo; + u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)prBufInfo->pucBuf) + >> MSG_BUF_BLOCK_SIZE_IN_POWER_OF_2; + ASSERT(u4BlockIndex < MAX_NUM_OF_BUF_BLOCKS); + eRamType = RAM_TYPE_MSG; + } + else if ( ((UINT_32)pvMemory >= (UINT_32)prAdapter->pucMgtBufCached) && + ((UINT_32)pvMemory <= ((UINT_32)prAdapter->pucMgtBufCached + MGT_BUFFER_SIZE -1))) { + prBufInfo = &prAdapter->rMgtBufInfo; + u4BlockIndex = ((UINT_32)pvMemory - (UINT_32)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; + + 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; + + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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) { + if(prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp) { + prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp(prAdapter, prBssInfo, FALSE); + } else { + ASSERT(0); + } + } + } +#endif + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + + DBGLOG(REQ, TRACE, ("STA "MACSTR" type=%d state = %d\n", MAC2STR(prStaRec->aucMacAddr), prStaRec->eStaType, prStaRec->ucStaState)); + + 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/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_timer.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_timer.c new file mode 100755 index 000000000000..021ff7ae8025 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/cnm_timer.c @@ -0,0 +1,575 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/cnm_timer.c#1 $ +*/ + +/*! \file "cnm_timer.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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 + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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; + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 */ + + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 UINT_32 u4Data + ) +{ + 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->u4Data = u4Data; + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + UINT_32 u4TimeoutData; + 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; + u4TimeoutData = prTimer->u4Data; + + 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, u4TimeoutData); + 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/mtk_wcn_combo/drv_wlan/wlan/mgmt/hem_mbox.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/hem_mbox.c new file mode 100755 index 000000000000..0558c97fbc9c --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/hem_mbox.c @@ -0,0 +1,844 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/hem_mbox.c#3 $ +*/ + +/*! \file "hem_mbox.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: hem_mbox.c $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 + * Add XLOG related code and define. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 08 11 2011 yuche.tsai + * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature. + * Add mailbox 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 cm.chang + * [WCXRP00000606] [MT6620 Wi-Fi][Driver][FW] Fix klocwork warning + * As CR titile + * + * 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_CANCEL"), + (PUINT_8)DISP_STRING("MID_P2P_SCN_SCAN_REQ"), + (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_CANCEL"), + (PUINT_8)DISP_STRING("MID_RLM_SCN_SCAN_REQ"), + (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_DISCOVERY_ABORT"), + (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_CONNECTION_TRIGGER"), + (PUINT_8)DISP_STRING("MID_MNY_P2P_CONNECTION_PAUSE"), + (PUINT_8)DISP_STRING("MID_MNY_P2P_PROVISION_COMPLETE"), + #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") +}; +/*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 }, + { MID_CNM_P2P_CH_GRANT, mboxDummy }, /*set in gl_p2p_init.c*/ + +#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 }, + { MID_SCN_P2P_SCAN_DONE, mboxDummy }, /*set in gl_p2p_init.c*/ + +#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, mboxDummy }, + { MID_P2P_SAA_FSM_ABORT, mboxDummy }, + { MID_SAA_P2P_JOIN_COMPLETE, mboxDummy },// TODO: p2pFsmRunEventJoinComplete + + { MID_MNY_P2P_FUN_SWITCH, mboxDummy }, + { MID_MNY_P2P_DEVICE_DISCOVERY, mboxDummy }, + { MID_MNY_P2P_DISCOVERY_ABORT, mboxDummy }, + { MID_MNY_P2P_CONNECTION_REQ, mboxDummy }, + { MID_MNY_P2P_CONNECTION_ABORT, mboxDummy }, + { MID_MNY_P2P_CONNECTION_TRIGGER,mboxDummy }, + { MID_MNY_P2P_CONNECTION_PAUSE, mboxDummy }, + { MID_MNY_P2P_PROVISION_COMPLETE,mboxDummy }, + { MID_MNY_P2P_INVITATION_REQ,mboxDummy }, + { MID_MNY_P2P_INVITATION_ABORT,mboxDummy }, + { MID_MNY_P2P_BEACON_UPDATE,mboxDummy }, + { MID_MNY_P2P_BEACON_DEL,mboxDummy }, + { MID_MNY_P2P_CHNL_REQ,mboxDummy }, + { MID_MNY_P2P_CHNL_ABORT,mboxDummy }, + { MID_MNY_P2P_MGMT_TX,mboxDummy }, + { MID_MNY_P2P_GROUP_DISSOLVE,mboxDummy }, + { MID_MNY_P2P_MGMT_FRAME_REGISTER, mboxDummy }, +#endif + +#if CFG_SUPPORT_ADHOC + { MID_SCN_AIS_FOUND_IBSS, aisFsmRunEventFoundIBSSPeer }, +#endif /* CFG_SUPPORT_ADHOC */ + + { MID_SAA_AIS_FSM_ABORT, aisFsmRunEventAbort } +}; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +#if CFG_SUPPORT_XLOG +#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) +#else +#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) +#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); + + return; +} + + +#if CFG_ENABLE_WIFI_DIRECT +EXPORT_SYMBOL(arMsgMapTable); +#endif + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/mib.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/mib.c new file mode 100755 index 000000000000..e1cc658d9dd7 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/mib.c @@ -0,0 +1,146 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/mib.c#1 $ +*/ + +/*! \file "mib.c" + \brief This file includes the mib default vale and functions. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: mib.c $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/mgmt/privacy.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/privacy.c new file mode 100755 index 000000000000..36d2c9bbba2c --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/privacy.c @@ -0,0 +1,1069 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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 + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 Microsoft os query + * remove the assert code for allow ad-hoc pkt. + * + * 04 13 2010 wh.su + * [BORA00000680][MT6620] Support the statistic for Microsoft 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, + (UINT_32)NULL); + +#if CFG_SUPPORT_802_11W + cnmTimerInitTimer(prAdapter, + &prAisSpecBssInfo->rSaQueryTimer, + (PFN_MGMT_TIMEOUT_FUNC)rsnStartSaQueryTimer, + (UINT_32)NULL); +#endif + + prAisSpecBssInfo->fgCounterMeasure = FALSE; + prAisSpecBssInfo->ucWEPDefaultKeyID = 0; + + + #if 0 + for (i=0;iarWtbl[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 +*/ +/*----------------------------------------------------------------------------*/ +BOOL +secCheckClassError ( + IN P_ADAPTER_T prAdapter, + IN P_SW_RFB_T prSwRfb, + IN P_STA_RECORD_T prStaRec + ) +{ + ASSERT(prAdapter); + ASSERT(prSwRfb); + //ASSERT(prStaRec); + + //prStaRec = &(g_arStaRec[prSwRfb->ucStaRecIdx]); + + if ((prStaRec) && 1 /* RXM_IS_DATA_FRAME(prSwRfb) */) { + ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex = prStaRec->ucNetTypeIndex; + + if (IS_NET_ACTIVE(prAdapter, eNetTypeIndex)) { + P_BSS_INFO_T prBssInfo; + prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]; + + if ((STA_STATE_3 != prStaRec->ucStaState) && + IS_BSS_ACTIVE(prBssInfo) && + prBssInfo->fgIsNetAbsent == FALSE) { + /*(IS_AP_STA(prStaRec) || IS_CLIENT_STA(prStaRec))) {*/ + + if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter, + prStaRec, + NULL, + REASON_CODE_CLASS_3_ERR, + (PFN_TX_DONE_HANDLER)NULL)) { + + DBGLOG(RSN, INFO, ("Send Deauth to MAC:["MACSTR"] for Rx Class 3 Error.\n", + MAC2STR(prStaRec->aucMacAddr))); + } + + return FALSE; + } + + return secRxPortControlCheck(prAdapter, prSwRfb); + } + } + + return FALSE; +} /* 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 "MACSTR" port %s\n", MAC2STR(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 +* +*/ +/*----------------------------------------------------------------------------*/ +BOOL /* 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(INIT, 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(INIT, 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 +* +*/ +/*----------------------------------------------------------------------------*/ +BOOL +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; + } + else { + DBGLOG(RSN, LOUD, ("1x Protected.\n")); + return TRUE; + } + } + else { + 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/mtk_wcn_combo/drv_wlan/wlan/mgmt/rate.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rate.c new file mode 100755 index 000000000000..9faea9d1f1d9 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rate.c @@ -0,0 +1,591 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rate.c $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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)) { + if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) // Reply ACK Frame at the same Modulation Scheme. + 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/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm.c new file mode 100755 index 000000000000..0ff9a32e3c76 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm.c @@ -0,0 +1,1788 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/rlm.c#1 $ +*/ + +/*! \file "rlm.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm.c $ + * + * 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 + * . + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 02 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 channel number validation method + * + * 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 IE channel is valid before recording BSS channel number + * + * 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 titile + * + * 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); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + } +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +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); + + /* 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); + } + + 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); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* +* \param[in] +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +static VOID +rlmFillExtCapIE ( + P_ADAPTER_T prAdapter, + P_BSS_INFO_T prBssInfo, + P_MSDU_INFO_T prMsduInfo + ) +{ + P_EXT_CAP_T prExtCap; + BOOLEAN fg40mAllowed; + + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + fg40mAllowed = prBssInfo->fgAssoc40mBwAllowed; + + /* Add Extended Capabilities IE */ + prExtCap = (P_EXT_CAP_T) + (((PUINT_8) prMsduInfo->prPacket) + prMsduInfo->u2FrameLength); + + prExtCap->ucId = ELEM_ID_EXTENDED_CAP; + prExtCap->ucLength = 1; + 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); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* +* \param[in] +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +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); + + 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); +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 vaild 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_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 + 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; + + ASSERT(prAdapter); + ASSERT(prBssInfo && prSwRfb); + ASSERT(pucIE); + + /* 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 + ) +{ + ASSERT(prAdapter); + ASSERT(prBssInfo && prSwRfb); + ASSERT(pucIE); + +#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 procesed 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) { + /* To do: Ad-hoc */ + } + + /* Appy new parameters if necessary */ + if (fgNewParameter) { + 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; + + if ((ucPriChannel = + rlmRecIeInfoForClient(prAdapter, prBssInfo, pucIE, u2IELength)) > 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() + */ +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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, INFO, ("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) { + + ASSERT(prAdapter->rP2pFuncLkr.prRlmBssInitForAP); + prAdapter->rP2pFuncLkr.prRlmBssInitForAP(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_ENABLE_WIFI_DIRECT +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* +* \param[in] +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +VOID +linkToRlmRspGenerateObssScanIE ( + P_ADAPTER_T prAdapter, + P_MSDU_INFO_T prMsduInfo + ) +{ + ASSERT(prAdapter); + ASSERT(prMsduInfo); + + if (prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prRlmRspGenerateObssScanIE); + + if (prAdapter->rP2pFuncLkr.prRlmRspGenerateObssScanIE) { + prAdapter->rP2pFuncLkr.prRlmRspGenerateObssScanIE( + prAdapter, prMsduInfo); + } + } + return; +} +#endif + +EXPORT_SYMBOL(rlmSyncOperationParams); + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_domain.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_domain.c new file mode 100755 index 000000000000..f6965640f186 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_domain.c @@ -0,0 +1,713 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/rlm_domain.c#1 $ +*/ + +/*! \file "rlm_domain.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm_domain.c $ + * + * 11 10 2011 cm.chang + * NULL + * Modify debug message for XLOG + * + * 11 02 2011 cm.chang + * NULL + * Format alignment + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 06 01 2011 cm.chang + * [WCXRP00000756] [MT6620 Wi-Fi][Driver] 1. AIS follow channel of BOW 2. Provide legal channel function + * Provide function to check if specified channel is legal 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 Netwrok. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 channle 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" + +/******************************************************************************* +* 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_US, COUNTRY_CODE_BS, COUNTRY_CODE_BB, COUNTRY_CODE_BO, COUNTRY_CODE_DM, + COUNTRY_CODE_DO, COUNTRY_CODE_HT, COUNTRY_CODE_PR, COUNTRY_CODE_TH, COUNTRY_CODE_TW, + COUNTRY_CODE_AI, COUNTRY_CODE_AG, COUNTRY_CODE_AW, COUNTRY_CODE_BM, COUNTRY_CODE_CU, + COUNTRY_CODE_GD, COUNTRY_CODE_GY, COUNTRY_CODE_JM, COUNTRY_CODE_KN, COUNTRY_CODE_LC, + COUNTRY_CODE_VC, COUNTRY_CODE_TT, COUNTRY_CODE_SR +}; +static const UINT_16 g_u2CountryGroup1[] = +{ + COUNTRY_CODE_BR, COUNTRY_CODE_EC, COUNTRY_CODE_HK, COUNTRY_CODE_MX, COUNTRY_CODE_PE, + COUNTRY_CODE_CR, COUNTRY_CODE_MD, COUNTRY_CODE_NI, COUNTRY_CODE_PZ +}; +static const UINT_16 g_u2CountryGroup2[] = {COUNTRY_CODE_CO, COUNTRY_CODE_PY}; +static const UINT_16 g_u2CountryGroup3[] = {COUNTRY_CODE_JP}; +static const UINT_16 g_u2CountryGroup4[] = +{ + COUNTRY_CODE_CN, COUNTRY_CODE_UY, COUNTRY_CODE_MA +}; +static const UINT_16 g_u2CountryGroup5[] = {COUNTRY_CODE_AR}; +static const UINT_16 g_u2CountryGroup6[] = {COUNTRY_CODE_AU, COUNTRY_CODE_NZ}; +static const UINT_16 g_u2CountryGroup7[] = {COUNTRY_CODE_RU}; +static const UINT_16 g_u2CountryGroup8[] = +{ + COUNTRY_CODE_ID, COUNTRY_CODE_HN, COUNTRY_CODE_PG, COUNTRY_CODE_PK +}; +static const UINT_16 g_u2CountryGroup9[] = {COUNTRY_CODE_CA}; +static const UINT_16 g_u2CountryGroup10[] = +{ + COUNTRY_CODE_CL, COUNTRY_CODE_IN, COUNTRY_CODE_SA, COUNTRY_CODE_SG, COUNTRY_CODE_VE, + COUNTRY_CODE_MY, COUNTRY_CODE_VN, COUNTRY_CODE_EG +}; +static const UINT_16 g_u2CountryGroup11[] = {COUNTRY_CODE_IL, COUNTRY_CODE_UA}; +static const UINT_16 g_u2CountryGroup12[] = {COUNTRY_CODE_JO, COUNTRY_CODE_KW}; +static const UINT_16 g_u2CountryGroup13[] = {COUNTRY_CODE_KR, COUNTRY_CODE_OM}; +static const UINT_16 g_u2CountryGroup14[] = +{ + COUNTRY_CODE_EU + /* When country code is not found, this domain info will be used. + * So mark all country codes to reduce search time. 20110908 + */ + /*, COUNTRY_CODE_PH, COUNTRY_CODE_TR, COUNTRY_CODE_IR, COUNTRY_CODE_BY, + COUNTRY_CODE_LK */ +}; + + +DOMAIN_INFO_ENTRY arSupportedRegDomains[] = { + { + (PUINT_16) g_u2CountryGroup0, sizeof(g_u2CountryGroup0) / 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_u2CountryGroup1, sizeof(g_u2CountryGroup1) / 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, 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_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, FALSE }, /* CH_SET_UNII_MID_52_64 */ + { 121, BAND_5G, CHNL_SPAN_20, 100, 11, FALSE }, /* 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_u2CountryGroup3, sizeof(g_u2CountryGroup3) / 2, + { + { 81, BAND_2G4, CHNL_SPAN_5, 1, 13, FALSE }, /* CH_SET_2G4_1_14 */ + { 82, BAND_2G4, CHNL_SPAN_5, 14, 1, FALSE }, + + { 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_NULL, 0, 0, 0, FALSE } /* CH_SET_UNII_UPPER_NA */ + } + }, + { + (PUINT_16) g_u2CountryGroup4, sizeof(g_u2CountryGroup4) / 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_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_u2CountryGroup5, sizeof(g_u2CountryGroup5) / 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_5G, CHNL_SPAN_20, 52, 4, FALSE }, /* 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_u2CountryGroup6, sizeof(g_u2CountryGroup6) / 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, 4, FALSE }, /* CH_SET_UNII_UPPER_149_161 */ + { 0, BAND_NULL, 0, 0, 0, FALSE } + } + }, + { + (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, 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, 4, FALSE }, /* CH_SET_UNII_UPPER_149_161 */ + { 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_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_u2CountryGroup9, sizeof(g_u2CountryGroup9) / 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, 5, FALSE }, /* CH_SET_UNII_WW_100_116_132_140 */ + { 121, BAND_5G, CHNL_SPAN_20, 132, 5, FALSE }, + { 125, BAND_5G, CHNL_SPAN_20, 149, 5, FALSE }, /* CH_SET_UNII_UPPER_149_165 */ + } + }, + { + (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, FALSE }, /* 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_5G, CHNL_SPAN_20, 52, 4, FALSE }, /* 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_u2CountryGroup12, sizeof(g_u2CountryGroup12) / 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_u2CountryGroup13, sizeof(g_u2CountryGroup13) / 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, 5, FALSE }, /* CH_SET_UNII_UPPER_149_165 */ + { 0, BAND_NULL, 0, 0, 0, FALSE } + } + }, + { + /* Note: The final one is for Europe union now. */ + (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, 11, FALSE }, /* CH_SET_UNII_WW_100_140 */ + { 125, BAND_5G, CHNL_SPAN_20, 149, 7, FALSE }, /* CH_SET_UNII_UPPER_149_173 */ + { 0, BAND_NULL, 0, 0, 0, FALSE } + } + } +}; + +#if 0 +COUNTRY_CH_SET_T arCountryChSets[] = { + /* idx=0: US, Bahamas, Barbados, Bolivia(Voluntary), Dominica (the Commonwealth of Dominica), + The Dominican Republic, Haiti */ + {CH_SET_2G4_1_11, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_149_165}, + /* idx=1: Brazil, Ecuador, Hong Kong, Mexico, Peru */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_149_165}, + /* idx=2: JP1, Colombia(Voluntary), Paraguay */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_NA}, + /* idx=3: JP2 */ + {CH_SET_2G4_1_14, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_NA}, + /* idx=4: CN, Uruguay, Morocco */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_NA, CH_SET_UNII_MID_NA, + CH_SET_UNII_WW_NA, CH_SET_UNII_UPPER_149_165}, + /* idx=5: Argentina */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_NA, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_NA, CH_SET_UNII_UPPER_149_165}, + /* idx=6: Australia, New Zealand */ + {CH_SET_2G4_1_11, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_149_161}, + /* idx=7: Russia */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_149_161}, + /* idx=8: Indonesia */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_NA, CH_SET_UNII_MID_NA, + CH_SET_UNII_WW_NA, CH_SET_UNII_UPPER_149_161}, + /* idx=9: Canada */ + {CH_SET_2G4_1_11, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_116_132_140, CH_SET_UNII_UPPER_149_165}, + /* idx=10: Chile, India, Saudi Arabia, Singapore */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_NA, CH_SET_UNII_UPPER_149_165}, + /* idx=11: Israel, Ukraine */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_NA, CH_SET_UNII_UPPER_NA}, + /* idx=12: Jordan, Kuwait */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_NA, + CH_SET_UNII_WW_NA, CH_SET_UNII_UPPER_NA}, + /* idx=13: South Korea */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_128, CH_SET_UNII_UPPER_149_165}, + /* idx=14: Taiwan */ + {CH_SET_2G4_1_11, CH_SET_UNII_LOW_NA, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_149_165}, + /* idx=15: EU all countries */ + {CH_SET_2G4_1_13, CH_SET_UNII_LOW_36_48, CH_SET_UNII_MID_52_64, + CH_SET_UNII_WW_100_140, CH_SET_UNII_UPPER_149_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 14 /* EU (Europe Union) */ +#define REG_DOMAIN_GROUP_NUM \ + (sizeof(arSupportedRegDomains) / sizeof(DOMAIN_INFO_ENTRY)) + + UINT_16 i, j; + P_DOMAIN_INFO_ENTRY prDomainInfo; + P_REG_INFO_T prRegInfo; + UINT_16 u2TargetCountryCode; + + ASSERT(prAdapter); + + if (prAdapter->prDomainInfo) { + return prAdapter->prDomainInfo; + } + + prRegInfo = &prAdapter->prGlueInfo->rRegInfo; + + DBGLOG(RLM, INFO, ("Domain: map=%d, idx=%d, code=0x%04x\n", + prRegInfo->eRegChannelListMap, prRegInfo->ucRegChannelListIndex, + prAdapter->rWifiVar.rConnSettings.u2CountryCode)); + + if (prRegInfo->eRegChannelListMap == REG_CH_MAP_TBL_IDX && + prRegInfo->ucRegChannelListIndex < REG_DOMAIN_GROUP_NUM) { + prDomainInfo = &arSupportedRegDomains[prRegInfo->ucRegChannelListIndex]; + goto L_set_domain_info; + } + else if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) { + prDomainInfo = &prRegInfo->rDomainInfo; + goto L_set_domain_info; + } + + u2TargetCountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; + + /* If no matched country code, the final one will be used + * The final one is for Europe union now. + */ + for (i = 0; i < REG_DOMAIN_GROUP_NUM; i++) { + prDomainInfo = &arSupportedRegDomains[i]; + + ASSERT((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 */ + } + } + + DATA_STRUC_INSPECTING_ASSERT(REG_DOMAIN_DEF_IDX < REG_DOMAIN_GROUP_NUM); + + if (i >= REG_DOMAIN_GROUP_NUM) { + prDomainInfo = &arSupportedRegDomains[REG_DOMAIN_DEF_IDX]; + } + +L_set_domain_info: + + 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, + 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); + + /* If no matched country code, the final one will be used */ + 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 (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 + ) +{ + P_DOMAIN_INFO_ENTRY prDomainInfo; + P_CMD_SET_DOMAIN_INFO_T prCmd; + WLAN_STATUS rStatus; + UINT_8 i; + P_DOMAIN_SUBBAND_INFO prSubBand; + + prDomainInfo = rlmDomainGetDomainInfo(prAdapter); + ASSERT(prDomainInfo); + + prCmd = cnmMemAlloc(prAdapter, RAM_TYPE_BUF, sizeof(CMD_SET_DOMAIN_INFO_T)); + ASSERT(prCmd); + + /* To do: exception handle */ + if (!prCmd) { + DBGLOG(RLM, ERROR, ("Domain: no buf to send cmd\n")); + return; + } + kalMemZero(prCmd, sizeof(CMD_SET_DOMAIN_INFO_T)); + + prCmd->u2CountryCode = prAdapter->rWifiVar.rConnSettings.u2CountryCode; + prCmd->u2Reserved = 0; + prCmd->uc2G4Bandwidth = + prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode; + prCmd->uc5GBandwidth = + prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode; + + for (i = 0; i < 6; 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; + } + } + + /* Update domain info to chip */ + rStatus = 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 */ + ); + + ASSERT(rStatus == WLAN_STATUS_PENDING); + + 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; +} + +EXPORT_SYMBOL(rlmDomainGetDomainInfo); + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_obss.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_obss.c new file mode 100755 index 000000000000..ef573727d6b0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_obss.c @@ -0,0 +1,502 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/rlm_obss.c#1 $ +*/ + +/*! \file "rlm_obss.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm_obss.c $ + * + * 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 + * . + * + * 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 titile + * + * 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, + UINT_32 u4Data + ); + +/******************************************************************************* +* 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, (UINT_32) 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. + */ + if ((prBssInfo->auc2G_20mReqChnlList[0] > 0 || + prBssInfo->auc2G_NonHtChnlList[0] > 0) && + (prMsduInfo = (P_MSDU_INFO_T) cnmMgtPktAlloc(prAdapter, + MAC_TX_RESERVED_FIELD + PUBLIC_ACTION_MAX_LEN)) != 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) + ((UINT_32)(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, + UINT_32 u4Data + ) +{ + P_BSS_INFO_T prBssInfo; + + prBssInfo = (P_BSS_INFO_T) u4Data; + ASSERT(prBssInfo); + +#if CFG_ENABLE_WIFI_DIRECT + /* AP mode */ + if (prAdapter->fgIsP2PRegistered && + (IS_NET_ACTIVE(prAdapter, prBssInfo->ucNetTypeIndex)) && + (prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT)) { + + prBssInfo->fgObssActionForcedTo20M = FALSE; + + /* Check if Beacon content need to be updated */ + ASSERT(prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp); + prAdapter->rP2pFuncLkr.prRlmUpdateParamsForAp( + prAdapter, prBssInfo, FALSE); + return; + } +#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/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_protection.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_protection.c new file mode 100755 index 000000000000..16941cb1b9e1 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rlm_protection.c @@ -0,0 +1,152 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/rlm_protection.c#1 $ +*/ + +/*! \file "rlm_protection.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rlm_protection.c $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/mgmt/roaming_fsm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/roaming_fsm.c new file mode 100755 index 000000000000..45b5d2326841 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/roaming_fsm.c @@ -0,0 +1,625 @@ +/* +** $Id: +*/ + +/*! \file "roaming_fsm.c" + \brief This file defines the FSM for Roaming MODULE. + + This file defines the FSM for Roaming MODULE. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: roaming_fsm.c $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 + * Add XLOG related code and define. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 = %ld\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; + + return; +} /* 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 = %ld\n", kalGetTimeTick())); + + prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo); + + prRoamingFsmInfo->eCurrentState = ROAMING_STATE_IDLE; + + return; +} /* 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 = %ld\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); + + return; +} /* 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 */ + ROAMING_ENABLE_CHECK(prRoamingFsmInfo); + + DBGLOG(ROAMING, LOUD, ("->roamingFsmScanResultsUpdate(): Current Time = %ld\n", kalGetTimeTick())); + + GET_CURRENT_SYSTIME(&prRoamingFsmInfo->rRoamingDiscoveryUpdateTime); + + return; +} /* 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 CFG_SUPPORT_XLOG + DBGLOG(ROAMING, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n", + DBG_ROAMING_IDX, + prRoamingFsmInfo->eCurrentState, + eNextState)); +#else + DBGLOG(ROAMING, STATE, ("TRANSITION: [%s] -> [%s]\n", + apucDebugRoamingState[prRoamingFsmInfo->eCurrentState], + apucDebugRoamingState[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")); + 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 */ + ROAMING_ENABLE_CHECK(prRoamingFsmInfo); + + prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]); + if (prAisBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) { + return; + } + + DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING START: Current Time = %ld\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); + } + + return; +} /* 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 UINT_32 u4Param + ) +{ + P_ROAMING_INFO_T prRoamingFsmInfo; + ENUM_ROAMING_STATE_T eNextState; + + prRoamingFsmInfo = (P_ROAMING_INFO_T)&(prAdapter->rWifiVar.rRoamingInfo); + + /* Check Roaming Conditions */ + ROAMING_ENABLE_CHECK(prRoamingFsmInfo); + + DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING DISCOVERY: Current Time = %ld\n", kalGetTimeTick())); + + /* DECISION -> DISCOVERY */ + /* Errors as IDLE, DISCOVERY, ROAM -> DISCOVERY */ + if (prRoamingFsmInfo->eCurrentState != ROAMING_STATE_DECISION) { + return; + } + + 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)(u4Param&0xff); + } + + roamingFsmSteps(prAdapter, eNextState); + } + + return; +} /* 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 */ + ROAMING_ENABLE_CHECK(prRoamingFsmInfo); + + DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING ROAM: Current Time = %ld\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); + } + + return; +} /* 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 */ + ROAMING_ENABLE_CHECK(prRoamingFsmInfo); + + DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING FAIL: reason %x Current Time = %ld\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); + } + + return; +} /* 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); + + ROAMING_ENABLE_CHECK(prRoamingFsmInfo); + + DBGLOG(ROAMING, EVENT, ("EVENT-ROAMING ABORT: Current Time = %ld\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); + } + + return; +} /* 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 = %ld\n", kalGetTimeTick())); + + if (ROAMING_EVENT_DISCOVERY == prParam->u2Event) { + roamingFsmRunEventDiscovery(prAdapter, prParam->u2Data); + } + + return WLAN_STATUS_SUCCESS; +} + +#endif diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rsn.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rsn.c new file mode 100755 index 000000000000..84aa4d677ca5 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/rsn.c @@ -0,0 +1,2653 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: rsn.c $ + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 01 30 2012 chinglan.wang + * [ALPS00118489] [Need Patch] [Volunteer Patch] [ICS] [Wi-Fi Direct] Update wpa_supplicant_8 (p2p supplicant) for ICS Wi-Fi direct mode. + * . + * + * 01 27 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Fix compile warning & update latest driver 2.2. + * Davinci Label: 20120127_ALPS_WIFI_P2P_DRIVER_V2_1 + * + * 01 19 2012 chinglan.wang + * NULL + * Support the WPA-PSK TKIP security mode for the tethering.. + * + * 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 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 indiate pmkid candidate while no new one scaned. + * + * 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 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; + } + else { + 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\n")); + 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\n")); + return TRUE; + } + + 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, + prBssRsnInfo->u4PairwiseKeyCipherSuiteCount, + 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%08lx/0x%08lx)\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%08lx/0x%08lx)\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) { + } + DBGLOG(RSN, TRACE, ("Failed to select pairwise/group cipher for BT over Wi-Fi network (0x%08lx/0x%08lx)\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%08lx/0x%08lx)\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)((UINT_32)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 avaiable 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; + + DEBUGFUNC("rsnGenerateWPAIE"); + + ASSERT(prMsduInfo); + + pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket + + (UINT_32)prMsduInfo->u2FrameLength); + + ASSERT(pucBuffer); + + eNetworkId = (ENUM_NETWORK_TYPE_INDEX_T)prMsduInfo->ucNetworkType; + + //if (eNetworkId != NETWORK_TYPE_AIS_INDEX) + // return; + + if ((1 /* prCurrentBss->fgIEWPA */ && +#if CFG_ENABLE_WIFI_DIRECT + ((prAdapter->fgIsP2PRegistered) && + (eNetworkId == NETWORK_TYPE_P2P_INDEX) && + (prAdapter->rP2pFuncLkr.prKalP2pGetTkipCipher(prAdapter->prGlueInfo)))) || +#endif + ((prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA) || + (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA_PSK))) + { + /* 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)((UINT_32)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) && + (prAdapter->rP2pFuncLkr.prKalP2pGetCcmpCipher(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 (eNetworkId == NETWORK_TYPE_AIS_INDEX && + rsnSearchPmkidEntry(prAdapter, prStaRec->aucMacAddr, &u4Entry)) { + //DBGLOG(RSN, TRACE, ("Add Pmk at assoc req\n")); + //DBGLOG(RSN, TRACE, ("addr " MACSTR" PMKID "MACSTR"\n", + // MAC2STR(prAdapter->rWifiVar.rAisSpecificBssInfo.arPmkidCache[u4Entry].rBssidInfo.arBSSID), MAC2STR(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 "MACSTR" ind=%d\n", MAC2STR(prStaRec->aucMacAddr), u4Entry)); + DBGLOG(RSN, TRACE, ("use PMKID "MACSTR"\n", MAC2STR(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); + + 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); +} /* 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 ["MACSTR"]\n", + // MAC2STR(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 " MACSTR " with pre-auth to candidate list\n", + MAC2STR(prAisSpecBssInfo->arPmkidCandicate[i].aucBssid))); + } + else { + prAisSpecBssInfo->arPmkidCandicate[i].u4PreAuthFlags = 0; + DBGLOG(RSN, TRACE, ("Add " MACSTR " without pre-auth to candidate list\n", + MAC2STR(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, (MACSTR" at PMKID cache!!\n", MAC2STR(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 "MACSTR" to PMKID cache!!\n", MAC2STR(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 UINT_32 u4Parm + ) +{ + 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); + } + + return; +} /* 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, (MACSTR" %d\n", MAC2STR(prPmkidEvent->arCandidateList[count].arBSSID), + prPmkidEvent->arCandidateList[count].u4Flags)); + count++; + } + } + + /* PMKID Candidate List */ + prPmkidEvent->u4Version = 1; + prPmkidEvent->u4NumCandidates = count; + DBGLOG(RSN, TRACE, ("rsnGeneratePmkidIndication #%d\n", 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)((UINT_32)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 */ + 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) + ((UINT_32)(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, INFO, ("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, INFO, ("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 " + MACSTR"\n", MAC2STR(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 " MACSTR"\n", MAC2STR(prStaRec->aucMacAddr))); + return; + } + DBGLOG(RSN, TRACE, ("IEEE 802.11: Sending SA Query Response to " + MACSTR"\n", MAC2STR(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) + ((UINT_32)(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=%lu)\n", (unsigned long) 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 " + MACSTR"\n", MAC2STR(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 + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/saa_fsm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/saa_fsm.c new file mode 100755 index 000000000000..d87862206d64 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/saa_fsm.c @@ -0,0 +1,2056 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/saa_fsm.c#1 $ +*/ + +/*! \file "saa_fsm.c" + \brief This file defines the FSM for SAA MODULE. + + This file defines the FSM for SAA MODULE. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: saa_fsm.c $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 + * Add XLOG related code and define. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 reseting 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 CFG_SUPPORT_XLOG + DBGLOG(SAA, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n", + DBG_SAA_IDX, + prStaRec->eAuthAssocState, + eNextState)); +#else + DBGLOG(SAA, STATE, ("TRANSITION: [%s] -> [%s]\n", + apucDebugAAState[prStaRec->eAuthAssocState], + apucDebugAAState[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) { + } + 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, + (UINT_32)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, + (UINT_32)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, + (UINT_32)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 + saaFsmSteps(prAdapter, prStaRec, SAA_STATE_SEND_AUTH1, (P_SW_RFB_T)NULL); + + return; +} /* 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) { + return WLAN_STATUS_INVALID_PACKET; + } + + ASSERT(prStaRec); + + DBGLOG(SAA, LOUD, ("EVENT-TX DONE: Current Time = %ld\n", kalGetTimeTick())); + + 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, + (UINT_32)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, + (UINT_32)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, + (UINT_32)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 = %ld\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; + } + + 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 = %ld\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); + } + + return; +} /* 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) { + 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 ["MACSTR"], Status Code = %d\n", + MAC2STR(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 ["MACSTR"], Status Code = %d\n", + MAC2STR(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 */ + } + + return; +} /* 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 ["MACSTR"], Status Code = %d\n", + MAC2STR(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; +#if DBG + P_WLAN_DEAUTH_FRAME_T prDeauthFrame; +#endif /* DBG */ + + + ASSERT(prSwRfb); + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + +#if DBG + prDeauthFrame = (P_WLAN_DEAUTH_FRAME_T) prSwRfb->pvHeader; + + DBGLOG(SAA, INFO, ("Rx Deauth frame from BSSID=["MACSTR"].\n", + MAC2STR(prDeauthFrame->aucBSSID))); +#endif /* DBG */ + + do { + + /* We should have the corresponding Sta Record. */ + if (!prStaRec) { + break; + } + + 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) { + + /* Check if this is the AP we are associated or associating with */ + if (authProcessRxDeauthFrame(prSwRfb, + prStaRec->aucMacAddr, + &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { + + 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); + + 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 */ + } + + } + + } + + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { + /* TODO(Kevin) */ + prAdapter->rP2pFuncLkr.prP2pFsmRunEventRxDeauthentication(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; +#if DBG + P_WLAN_DISASSOC_FRAME_T prDisassocFrame; +#endif /* DBG */ + + + ASSERT(prSwRfb); + prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx); + +#if DBG + prDisassocFrame = (P_WLAN_DISASSOC_FRAME_T) prSwRfb->pvHeader; + + DBGLOG(SAA, INFO, ("Rx Disassoc frame from BSSID=["MACSTR"].\n", + MAC2STR(prDisassocFrame->aucBSSID))); +#endif /* DBG */ + + do { + + /* We should have the corresponding Sta Record. */ + if (!prStaRec) { + break; + } + + 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) { + + /* Check if this is the AP we are associated or associating with */ + if (assocProcessRxDisassocFrame(prAdapter, + prSwRfb, + prStaRec->aucMacAddr, + &prStaRec->u2ReasonCode) == WLAN_STATUS_SUCCESS) { + + if (STA_STATE_3 == prStaRec->ucStaState) { + P_MSG_AIS_ABORT_T prAisAbortMsg; + + 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 */ + } + + } + + } + + } +#if CFG_ENABLE_WIFI_DIRECT + else if (prAdapter->fgIsP2PRegistered && IS_STA_IN_P2P(prStaRec)) { + /* TODO(Kevin) */ + prAdapter->rP2pFuncLkr.prP2pFsmRunEventRxDisassociation(prAdapter, prStaRec, prSwRfb); + } +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if (IS_STA_IN_BOW(prStaRec)) { + /* 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 + } + + /* For the Auth/Assoc State to IDLE */ + prStaRec->eAuthAssocState = AA_STATE_IDLE; + + return; +} /* 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; + + return; +} /* 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); + return; +} /* 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: ["MACSTR"]\n", MAC2STR(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 Infomation + if (prAdapter->fgIsEnableWMM && + (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_SUPPORT_WMM)) { + + prBssInfo->fgIsWmmAssoc = TRUE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC3; + + qosWmmInfoInit(&prBssInfo->rWmmInfo, (prBssInfo->ePhyType == PHY_TYPE_HR_DSSS_INDEX) ? TRUE : FALSE); + + if (prPeerBssInfo->rWmmInfo.ucWmmFlag & WMM_FLAG_AC_PARAM_PRESENT) { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, + sizeof(WMM_INFO_T)); + } + else { + kalMemCopy(&prBssInfo->rWmmInfo, + &prPeerBssInfo->rWmmInfo, + sizeof(WMM_INFO_T) - sizeof(prPeerBssInfo->rWmmInfo.arWmmAcParams)); + } + } + else { + prBssInfo->fgIsWmmAssoc = FALSE; + prTxCtrl->rTxQForVoipAccess = TXQ_AC1; + + kalMemZero(&prBssInfo->rWmmInfo, sizeof(WMM_INFO_T)); + } + + + //4 <3.C> Operational Rate Set & BSS Basic Rate Set + prBssInfo->u2OperationalRateSet = prPeerBssInfo->u2OperationalRateSet; + prBssInfo->u2BSSBasicRateSet = prPeerBssInfo->u2BSSBasicRateSet; + + + //4 <3.D> Short Preamble + if (prBssInfo->fgIsERPPresent) { + + /* NOTE(Kevin 2007/12/24): Truth Table. + * Short Preamble Bit in + * Final Driver Setting(Short) + * TRUE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) + * TRUE FALSE TRUE FALSE + * FALSE FALSE FALSE FALSE(shouldn't have such case, use the AssocResp) + * FALSE FALSE TRUE FALSE + * TRUE TRUE FALSE TRUE(follow ERP) + * TRUE TRUE TRUE FALSE(follow ERP) + * FALSE TRUE FALSE FALSE(shouldn't have such case, and we should set to FALSE) + * FALSE TRUE TRUE FALSE(we should set to FALSE) + */ + if ((prPeerBssInfo->fgIsShortPreambleAllowed) && + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_SHORT) || /* Short Preamble Option Enable is TRUE */ + ((prConnSettings->ePreambleType == PREAMBLE_TYPE_AUTO) && + (prBssDesc->u2CapInfo & CAP_INFO_SHORT_PREAMBLE)))) { + + prBssInfo->fgIsShortPreambleAllowed = TRUE; + + if (prBssInfo->ucERP & ERP_INFO_BARKER_PREAMBLE_MODE) { + prBssInfo->fgUseShortPreamble = FALSE; + } + else { + prBssInfo->fgUseShortPreamble = TRUE; + } + } + else { + prBssInfo->fgIsShortPreambleAllowed = FALSE; + prBssInfo->fgUseShortPreamble = FALSE; + } + } + else { + /* NOTE(Kevin 2007/12/24): Truth Table. + * Short Preamble Bit in + * Final Driver Setting(Short) + * TRUE FALSE FALSE + * FALSE FALSE FALSE + * TRUE TRUE TRUE + * FALSE TRUE(status success) TRUE + * --> Honor the result of prPeerBssInfo. + */ + + prBssInfo->fgIsShortPreambleAllowed = prBssInfo->fgUseShortPreamble = + prPeerBssInfo->fgIsShortPreambleAllowed; + } + + DBGLOG(JOIN, INFO, ("prBssInfo->fgIsShortPreambleAllowed = %d, prBssInfo->fgUseShortPreamble = %d\n", + prBssInfo->fgIsShortPreambleAllowed, prBssInfo->fgUseShortPreamble)); + + + //4 <3.E> Short Slot Time + prBssInfo->fgUseShortSlotTime = + prPeerBssInfo->fgUseShortSlotTime; /* AP support Short Slot Time */ + + DBGLOG(JOIN, INFO, ("prBssInfo->fgUseShortSlotTime = %d\n", + prBssInfo->fgUseShortSlotTime)); + + nicSetSlotTime(prAdapter, + prBssInfo->ePhyType, + ((prConnSettings->fgIsShortSlotTimeOptionEnable && + prBssInfo->fgUseShortSlotTime) ? TRUE : FALSE)); + + + //4 <3.F> Update Tx Rate for Control Frame + bssUpdateTxRateForControlFrame(prAdapter); + + + //4 <3.G> Save the available Auth Types during Roaming (Design for Fast BSS Transition). + //if (prAdapter->fgIsEnableRoaming) /* NOTE(Kevin): Always prepare info for roaming */ + { + + if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_OPEN_SYSTEM) { + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_OPEN_SYSTEM; + } + else if (prJoinInfo->ucCurrAuthAlgNum == AUTH_ALGORITHM_NUM_SHARED_KEY) { + prJoinInfo->ucRoamingAuthTypes |= AUTH_TYPE_SHARED_KEY; + } + + prBssInfo->ucRoamingAuthTypes = prJoinInfo->ucRoamingAuthTypes; + + + /* Set the stable time of the associated BSS. We won't do roaming decision + * during the stable time. + */ + SET_EXPIRATION_TIME(prBssInfo->rRoamingStableExpirationTime, + SEC_TO_SYSTIME(ROAMING_STABLE_TIMEOUT_SEC)); + } + + + //4 <3.H> Update Parameter for TX Fragmentation Threshold +#if CFG_TX_FRAGMENT + txFragInfoUpdate(prAdapter); +#endif /* CFG_TX_FRAGMENT */ + + +//4 <4> Update STA_RECORD_T + /* Get a Station Record if possible */ + prStaRec = staRecGetStaRecordByAddr(prAdapter, + prBssDesc->aucBSSID); + + if (prStaRec) { + UINT_16 u2OperationalRateSet, u2DesiredRateSet; + + //4 <4.A> Desired Rate Set + u2OperationalRateSet = (rPhyAttributes[prBssInfo->ePhyType].u2SupportedRateSet & + prBssInfo->u2OperationalRateSet); + + u2DesiredRateSet = (u2OperationalRateSet & prConnSettings->u2DesiredRateSet); + if (u2DesiredRateSet) { + prStaRec->u2DesiredRateSet = u2DesiredRateSet; + } + else { + /* For Error Handling - The Desired Rate Set is not covered in Operational Rate Set. */ + prStaRec->u2DesiredRateSet = u2OperationalRateSet; + } + + /* Try to set the best initial rate for this entry */ + if (!rateGetBestInitialRateIndex(prStaRec->u2DesiredRateSet, + prStaRec->rRcpi, + &prStaRec->ucCurrRate1Index)) { + + if (!rateGetLowestRateIndexFromRateSet(prStaRec->u2DesiredRateSet, + &prStaRec->ucCurrRate1Index)) { + ASSERT(0); + } + } + + DBGLOG(JOIN, INFO, ("prStaRec->ucCurrRate1Index = %d\n", + prStaRec->ucCurrRate1Index)); + + //4 <4.B> Preamble Mode + prStaRec->fgIsShortPreambleOptionEnable = + prBssInfo->fgUseShortPreamble; + + //4 <4.C> QoS Flag + prStaRec->fgIsQoS = prBssInfo->fgIsWmmAssoc; + } +#if DBG + else { + ASSERT(0); + } +#endif /* DBG */ + + +//4 <5> Update NIC + //4 <5.A> Update BSSID & Operation Mode + nicSetupBSS(prAdapter, prBssInfo); + + //4 <5.B> Update WLAN Table. + if (nicSetHwBySta(prAdapter, prStaRec) == FALSE) { + ASSERT(FALSE); + } + + //4 <5.C> Update Desired Rate Set for BT. +#if CFG_TX_FRAGMENT + if (prConnSettings->fgIsEnableTxAutoFragmentForBT) { + txRateSetInitForBT(prAdapter, prStaRec); + } +#endif /* CFG_TX_FRAGMENT */ + + //4 <5.D> TX AC Parameter and TX/RX Queue Control + if (prBssInfo->fgIsWmmAssoc) { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, FALSE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + qosUpdateWMMParametersAndAssignAllowedACI(prAdapter, &prBssInfo->rWmmInfo); + } + else { + +#if CFG_TX_AGGREGATE_HW_FIFO + nicTxAggregateTXQ(prAdapter, TRUE); +#endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxNonQoSAssignDefaultAdmittedTXQ(prAdapter); + + nicTxNonQoSUpdateTXQParameters(prAdapter, + prBssInfo->ePhyType); + } + +#if CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN + { + prTxCtrl->fgBlockTxDuringJoin = FALSE; + + #if !CFG_TX_AGGREGATE_HW_FIFO /* TX FIFO AGGREGATE already do flush once */ + nicTxFlushStopQueues(prAdapter, (UINT_8)TXQ_DATA_MASK, (UINT_8)NULL); + #endif /* CFG_TX_AGGREGATE_HW_FIFO */ + + nicTxRetransmitOfSendWaitQue(prAdapter); + + if (prTxCtrl->fgIsPacketInOsSendQueue) { + nicTxRetransmitOfOsSendQue(prAdapter); + } + + #if CFG_SDIO_TX_ENHANCE + halTxLeftClusteredMpdu(prAdapter); + #endif /* CFG_SDIO_TX_ENHANCE */ + + } +#endif /* CFG_TX_STOP_WRITE_TX_FIFO_UNTIL_JOIN */ + + +//4 <6> Setup CONNECTION flag. + prAdapter->eConnectionState = MEDIA_STATE_CONNECTED; + prAdapter->eConnectionStateIndicated = MEDIA_STATE_CONNECTED; + + if (prJoinInfo->fgIsReAssoc) { + prAdapter->fgBypassPortCtrlForRoaming = TRUE; + } + else { + prAdapter->fgBypassPortCtrlForRoaming = FALSE; + } + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_CONNECT, + (PVOID)NULL, + 0); + + return; +} /* end of joinComplete() */ +#endif + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan.c new file mode 100755 index 000000000000..94e3aab8353f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan.c @@ -0,0 +1,3002 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/scan.c#5 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: scan.c $ + * + * 02 06 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Small bug fix for CNM memory usage, scan SSID search issue, P2P network deactivate issue. + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 01 16 2012 yuche.tsai + * NULL + * Fix compile error. + * + * 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. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 12 06 2011 cp.wu + * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path + * sync. for connect-by-bssid control path implementations. + * + * 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. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 26 2011 yuche.tsai + * [WCXRP00000875] [Volunteer Patch][WiFi Direct][Driver] MT6620 IOT issue with realtek test bed solution. + * P2P Scan would not check SSID field, because this field may change. + * + * 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 channel number validation method + * + * 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 IE channel is valid before recording BSS channel number + * + * 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. + * + * 04 11 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Alway keep the latest Bss type when RX Beacon. + * + * 03 23 2011 yuche.tsai + * NULL + * Fix concurrent issue when AIS scan result would over write P2P scan result. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 continous memory demands + * 1) correct typo in scan.c + * 2) TX descriptors, RX descriptos and management buffer should use virtually continous 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 occured + * + * 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 Microsoft 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 Microsoft 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(((UINT_32)pucBSSBuff - (UINT_32)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE); + + /* reset freest channel information */ + prScanInfo->fgIsSparseChannelValid = FALSE; + + return; +} /* 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); + + return; +} /* 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; + } + else { + 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; + } + else { + 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() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + + 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; + } + else { // CASE III + P_LINK_T prBSSDescList; + P_LINK_T prFreeBSSDescList; + + + 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: "MACSTR", Current Time = %08lx, Update Time = %08lx\n", + //prBssDesc, MAC2STR(prBssDesc->aucBSSID), rCurrentTime, prBssDesc->rUpdateTime)); + + /* Remove this BSS Desc from the BSS Desc list */ + LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc); +#if 0 //CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc); + prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc(prAdapter, prBssDesc); + } +#endif + /* 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: "MACSTR", Update Time = %08lx\n", + //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime)); + + /* Remove this BSS Desc from the BSS Desc list */ + LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest); +#if 0 //CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc); + prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc(prAdapter, prBssDescOldest); + } +#endif + /* 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: "MACSTR", Update Time = %08lx\n", + //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime)); + + /* Remove this BSS Desc from the BSS Desc list */ + LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest); +#if 0 //CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc); + prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc(prAdapter, prBssDescWeakest); + } + +#endif + /* 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); +#if 0 //CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc); + prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc(prAdapter, prBssDesc); + } +#endif + /* 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); +#if 0 //CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc); + prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc(prAdapter, prBssDesc); + } +#endif + + /* 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 */ + } + } + + return; +} /* 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); +#if 0 //CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc); + prAdapter->rP2pFuncLkr.prScanRemoveP2pBssDesc(prAdapter, prBssDesc); + } +#endif + + /* Return this BSS Desc to the free BSS Desc list. */ + LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry); + } + } + + return; +} /* 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; + + UINT_32 i; + UINT_8 ucSSIDChar; + + 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: + 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; + } + + 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/ASUS 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; + } + } + + + //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) { + 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 + //ASSERT(0); // still no space available ? + DBGLOG(SCN, WARN, ("BSS_DESC allocation failure\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); + + prBssDesc->eBSSType = eBSSType; + + 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) { + return prBssDesc; + } + // for received beacons too close in time domain + else if(rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) { + 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) { + scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID); + + prBssDesc = scanAllocateBssDesc(prAdapter); + if (!prBssDesc) { + return NULL; + } + } + } + + /* NOTE: Keep consistency of Scan Record during JOIN process */ + if (prBssDesc->fgIsConnecting) { + 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/ASUS 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); + } + + } + 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 + { + UINT_8 ucOuiType; + UINT_16 u2SubTypeVersion; +#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) { + ASSERT(prAdapter->rP2pFuncLkr.prP2pParseCheckForP2pInfoElem); + if (prAdapter->rP2pFuncLkr.prP2pParseCheckForP2pInfoElem(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; + } + + 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)((UINT_32)(prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN)); + + return WLAN_STATUS_SUCCESS; + +} /* end of scanAddScanResult() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* @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)) { +#ifndef _lint + ASSERT(0); +#endif /* _lint */ + return rStatus; + } + +#if CFG_SLT_SUPPORT + prSltInfo = &prAdapter->rWifiVar.rSltInfo; + + if (prSltInfo->fgIsDUT) { + DBGLOG(P2P, 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; + + //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 + + // <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 && + rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) { + ENUM_BAND_T eBand; + UINT_8 ucChannel; + BOOLEAN fgAddToScanResult; + + /* check ucChannelNum/eBand for adjacement channel filtering */ + if(cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE && + (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) { + DBGLOG(SCN, WARN, ("BSS Droppeed ["MACSTR"] on ch:#%d\n", MAC2STR(prBssDesc->aucBSSID), prBssDesc->ucChannelNum)); + fgAddToScanResult = FALSE; + } + else { + fgAddToScanResult = TRUE; + } + + if(fgAddToScanResult == TRUE) { + rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb); + } + } + } + +#if CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prScanP2pProcessBeaconAndProbeResp); + prAdapter->rP2pFuncLkr.prScanP2pProcessBeaconAndProbeResp( + 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; + + /* 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; + UINT_8 ucChannel; + + ASSERT(prAdapter); + + prConnSettings = &(prAdapter->rWifiVar.rConnSettings); + prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]); + + prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prBSSDescList = &prScanInfo->rBSSDescList; + + /* check for fixed channel operation */ + if(eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { + fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel); + } + else { + fgIsFixedChannel = FALSE; + } + +#if DBG + if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) { + prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0'; + } +#endif + + DBGLOG(SCN, INFO, ("SEARCH: Num Of BSS_DESC_T = %d, Look for SSID: %s\n", + prBSSDescList->u4NumElem, prConnSettings->aucSSID)); + + + //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, INFO, ("SEARCH: ["MACSTR"], SSID:%s\n", + MAC2STR(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, INFO, ("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 <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) { + OS_SYSTIME rCurrentTime; + + + GET_CURRENT_SYSTIME(&rCurrentTime); + + /* 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 which has Status Code = %d (Curr = %ld/Last Join = %ld)\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)) || + ((prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) && + (prBssDesc->eBSSType != BSS_TYPE_IBSS))) { + + DBGLOG(SCN, INFO, ("SEARCH: Ignore eBSSType = %s\n", + ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) ? + "INFRASTRUCTURE" : "IBSS"))); + 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, INFO, ("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:["MACSTR"]\n\n", + MAC2STR(prBssDesc->aucBSSID))); + continue; + } + + //4 <4.3.2> Check Peer's capability + if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) { + + DBGLOG(SCN, INFO, + ("SEARCH: Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n", + MAC2STR(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: ["MACSTR"], Smaller TSF\n", MAC2STR(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:["MACSTR"]\n\n", + MAC2STR(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:["MACSTR"]\n\n", + MAC2STR(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: "MACSTR", Capability is not supported for current AdHoc Mode.\n", + MAC2STR(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: ["MACSTR"], Current BSSID: ["MACSTR"].\n", + MAC2STR(prPrimaryBssDesc->aucBSSID), MAC2STR(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; + } + 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) { + if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) { + fgIsFindFirst = TRUE; + } + else { + /* Can't pass the Encryption Status Check, get next one */ + 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 "MACSTR"\n", + MAC2STR(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: "MACSTR" has nonzero Status Code = %d\n", + MAC2STR(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 ["MACSTR"]: RCPI = %d, Primary ["MACSTR"]: RCPI = %d\n", + MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateBssDesc->ucRCPI, + MAC2STR(prPrimaryBssDesc->aucBSSID), prPrimaryBssDesc->ucRCPI)); + + ASSERT(!(prCandidateBssDesc->fgIsConnected && + prPrimaryBssDesc->fgIsConnected)); + + /* 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) { + + prCandidateBssDesc = prPrimaryBssDesc; + prCandidateStaRec = prPrimaryStaRec; + continue; + } + } + else if (prPrimaryBssDesc->fgIsConnected) { + if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) { + + prCandidateBssDesc = prPrimaryBssDesc; + prCandidateStaRec = prPrimaryStaRec; + continue; + } + } + else if (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) { + + /* TODO(Kevin): Check which one has minimum channel load in its channel */ + } +#endif + } + } + + return prCandidateBssDesc; + +} /* end of scanSearchBssDescByPolicy() */ + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan_fsm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan_fsm.c new file mode 100755 index 000000000000..998cb9b9c8a7 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/scan_fsm.c @@ -0,0 +1,1159 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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 . +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: scan_fsm.c $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 + * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. + * Avoid possible FW assert when unload P2P module. + * + * 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 + * Add XLOG related code and define. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 */ + +/******************************************************************************* +* M A 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 CFG_SUPPORT_XLOG + DBGLOG(SCN, STATE, ("[%d] TRANSITION: [%d] -> [%d]\n", + DBG_SCN_IDX, + prScanInfo->eCurrentState, + eNextState)); +#else + DBGLOG(SCN, STATE, ("TRANSITION: [%s] -> [%s]\n", + apucDebugScanState[prScanInfo->eCurrentState], + apucDebugScanState[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); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + UINT_32 i; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + // send command packet for scan + kalMemZero(&rCmdScanReq, sizeof(CMD_SCAN_REQ)); + + rCmdScanReq.ucSeqNum = prScanParam->ucSeqNum; + rCmdScanReq.ucNetworkType = (UINT_8)prScanParam->eNetTypeIndex; + rCmdScanReq.ucScanType = (UINT_8)prScanParam->eScanType; + rCmdScanReq.ucSSIDType = prScanParam->ucSSIDType; + + if(prScanParam->ucSSIDNum == 1) { + COPY_SSID(rCmdScanReq.aucSSID, + rCmdScanReq.ucSSIDLength, + prScanParam->aucSpecifiedSSID[0], + prScanParam->ucSpecifiedSSIDLen[0]); + } + + rCmdScanReq.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) + */ + rCmdScanReq.ucChannelListNum = prScanParam->ucChannelListNum; + + for(i = 0 ; i < rCmdScanReq.ucChannelListNum ; i++) { + rCmdScanReq.arChannelList[i].ucBand = + (UINT_8) prScanParam->arChnlInfoList[i].eBand; + + rCmdScanReq.arChannelList[i].ucChannelNum = + (UINT_8)prScanParam->arChnlInfoList[i].ucChannelNum; + } + } + +#if CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + rCmdScanReq.u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; + } +#endif + + if(prScanParam->u2IELen <= MAX_IE_LENGTH) { + rCmdScanReq.u2IELen = prScanParam->u2IELen; + } + else { + rCmdScanReq.u2IELen = MAX_IE_LENGTH; + } + + if (prScanParam->u2IELen) { + kalMemCopy(rCmdScanReq.aucIE, + prScanParam->aucIE, + sizeof(UINT_8) * rCmdScanReq.u2IELen); + } + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SCAN_REQ, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + OFFSET_OF(CMD_SCAN_REQ, aucIE) + rCmdScanReq.u2IELen, + (PUINT_8)&rCmdScanReq, + NULL, + 0); +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + UINT_32 i; + + ASSERT(prAdapter); + + prScanInfo = &(prAdapter->rWifiVar.rScanInfo); + prScanParam = &prScanInfo->rScanParam; + + // send command packet for scan + kalMemZero(&rCmdScanReq, sizeof(CMD_SCAN_REQ_V2)); + + rCmdScanReq.ucSeqNum = prScanParam->ucSeqNum; + rCmdScanReq.ucNetworkType = (UINT_8)prScanParam->eNetTypeIndex; + rCmdScanReq.ucScanType = (UINT_8)prScanParam->eScanType; + rCmdScanReq.ucSSIDType = prScanParam->ucSSIDType; + + for (i = 0 ; i < prScanParam->ucSSIDNum; i++) { + COPY_SSID(rCmdScanReq.arSSID[i].aucSsid, + rCmdScanReq.arSSID[i].u4SsidLen, + prScanParam->aucSpecifiedSSID[i], + prScanParam->ucSpecifiedSSIDLen[i]); + } + + rCmdScanReq.u2ProbeDelayTime = (UINT_8)prScanParam->u2ProbeDelayTime; + rCmdScanReq.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) + */ + rCmdScanReq.ucChannelListNum = prScanParam->ucChannelListNum; + + for(i = 0 ; i < rCmdScanReq.ucChannelListNum ; i++) { + rCmdScanReq.arChannelList[i].ucBand = + (UINT_8) prScanParam->arChnlInfoList[i].eBand; + + rCmdScanReq.arChannelList[i].ucChannelNum = + (UINT_8)prScanParam->arChnlInfoList[i].ucChannelNum; + } + } + +#if CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered) { + rCmdScanReq.u2ChannelDwellTime = prScanParam->u2PassiveListenInterval; + } +#endif + + if(prScanParam->u2IELen <= MAX_IE_LENGTH) { + rCmdScanReq.u2IELen = prScanParam->u2IELen; + } + else { + rCmdScanReq.u2IELen = MAX_IE_LENGTH; + } + + if (prScanParam->u2IELen) { + kalMemCopy(rCmdScanReq.aucIE, + prScanParam->aucIE, + sizeof(UINT_8) * rCmdScanReq.u2IELen); + } + + wlanSendSetQueryCmd(prAdapter, + CMD_ID_SCAN_REQ_V2, + TRUE, + FALSE, + FALSE, + NULL, + NULL, + OFFSET_OF(CMD_SCAN_REQ_V2, aucIE) + rCmdScanReq.u2IELen, + (PUINT_8)&rCmdScanReq, + NULL, + 0); + +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + } + + return; +} + + + +/*----------------------------------------------------------------------------*/ +/*! +* \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(prAdapter->fgIsP2PRegistered) { + 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); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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(prAdapter->fgIsP2PRegistered) { + 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; + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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(prAdapter->fgIsP2PRegistered) { + 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; + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + } + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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, LOUD, ("Unexpected SCAN-DONE event: SeqNum = %d, Current State = %d\n", + prScanDone->ucSeqNum, + prScanInfo->eCurrentState)); + } + + return; +} /* 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; + + 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: + DBGLOG(SCN, LOUD, ("Unexpected Network Type: %d\n", ucNetTypeIndex)); + 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; + } +} + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/sec_fsm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/sec_fsm.c new file mode 100755 index 000000000000..37d66653b473 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/sec_fsm.c @@ -0,0 +1,1306 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: sec_fsm.c $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 + * Add XLOG related code and define. + * + * 03 29 2011 wh.su + * [WCXRP00000248] [MT6620 Wi-Fi][FW]Fixed the Klockwork error + * fixed the kclocwork error. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 Microsoft 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, + (UINT_32)prSta); + + cnmTimerInitTimer(prAdapter, + &prAdapter->rWifiVar.rAisSpecificBssInfo.rRsnaBlockTrafficTimer, + (PFN_MGMT_TIMEOUT_FUNC)secFsmEventEndOfCounterMeasure, + (UINT_32)prSta); + + } + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +secFsmTrans_INIT_to_CHECK_OK ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prSta + ) +{ + secSetPortBlocked(prAdapter, prSta, FALSE); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +secFsmTrans_INIT_to_INITIATOR_PORT_BLOCKED ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prSta + ) +{ + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +secFsmTrans_INIT_to_RESPONDER_PORT_BLOCKED ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prSta + ) +{ + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +secFsmTrans_INITIATOR_PORT_BLOCKED_to_CHECK_OK ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prSta + ) +{ + secSetPortBlocked(prAdapter, prSta, FALSE); + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +secFsmTrans_RESPONDER_PORT_BLOCKED_to_CHECK_OK ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prSta + ) +{ + secSetPortBlocked(prAdapter, prSta, FALSE); + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 - +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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)); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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 - +*/ +/*----------------------------------------------------------------------------*/ +__KAL_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)); + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 - +*/ +/*----------------------------------------------------------------------------*/ +__KAL_INLINE__ VOID +secFsmTrans_COUNTERMEASURE_to_INIT ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prSta + ) +{ + + //Clear the counter measure flag + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 CFG_SUPPORT_XLOG + DBGLOG(RSN, STATE, ("\n"MACSTR" [%d] TRANSITION: [%d] -> [%d]\n\n", + MAC2STR(prSta->aucMacAddr), + DBG_RSN_IDX, + prSecInfo->eCurrentState, + eNextState)); +#else + /* Do entering Next State */ + DBGLOG(RSN, STATE, ("\n"MACSTR" TRANSITION: [%s] -> [%s]\n\n", + MAC2STR(prSta->aucMacAddr), + apucDebugSecState[prSecInfo->eCurrentState], + apucDebugSecState[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 "MACSTR" network %d\n", + MAC2STR(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); + } + + return; +} /* 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 "MACSTR" network %d\n", + MAC2STR(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 CFG_SUPPORT_XLOG + DBGLOG(RSN, TRACE, (MACSTR" Sec state [%d]\n", MAC2STR(prSta->aucMacAddr), prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, TRACE, (MACSTR" Sec state %s\n", MAC2STR(prSta->aucMacAddr), + apucDebugSecState[prSecInfo->eCurrentState])); +#endif + + switch(prSecInfo->eCurrentState) { + case SEC_STATE_INITIATOR_PORT_BLOCKED : + case SEC_STATE_CHECK_OK : + prSecInfo->fg2nd1xSend = TRUE; + break; + default: +#if CFG_SUPPORT_XLOG + DBGLOG(RSN, WARN, ("Rcv 2nd EAPoL at [%d]\n", prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, WARN, ("Rcv 2nd EAPoL at %s\n", apucDebugSecState[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 CFG_SUPPORT_XLOG + DBGLOG(RSN, TRACE, (MACSTR " Sec state [%d]\n", MAC2STR(prSta->aucMacAddr), prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, TRACE, (MACSTR " Sec state %s\n", MAC2STR(prSta->aucMacAddr), + apucDebugSecState[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 CFG_SUPPORT_XLOG + DBGLOG(RSN, WARN, ("Rcv thh EAPoL Tx done at [%d]\n", prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, WARN, ("Rcv thh EAPoL Tx done at %s\n", apucDebugSecState[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 CFG_SUPPORT_XLOG + DBGLOG(RSN, TRACE, (MACSTR " Sec state [%d]\n", MAC2STR(prSta->aucMacAddr), prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, TRACE, (MACSTR " Sec state %s\n", MAC2STR(prSta->aucMacAddr), + apucDebugSecState[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 CFG_SUPPORT_XLOG + DBGLOG(RSN, TRACE, (MACSTR " Sec state [%d]\n", MAC2STR(prSta->aucMacAddr), prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, TRACE, (MACSTR " Sec state %s\n", MAC2STR(prSta->aucMacAddr), + apucDebugSecState[prSecInfo->eCurrentState])); +#endif + + prAdapter->rWifiVar.rAisSpecificBssInfo.u4RsnaLastMICFailTime = 0; + + switch(prSecInfo->eCurrentState) { + case SEC_STATE_CHECK_OK: + { + prAdapter->rWifiVar.rAisSpecificBssInfo.fgCounterMeasure = TRUE; + + // dls port control + SEC_STATE_TRANSITION(prAdapter, prSta, CHECK_OK, SEND_EAPOL); + } + break; + + default: + break; + } + + /* Call arbFsmSteps() when we are going to change ARB STATE */ + if (prSecInfo->eCurrentState != eNextState) { + secFsmSteps(prAdapter, prSta, eNextState); + } + + return; + +} /* secFsmRunEventStartCounterMeasure */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will indicate an Event of "802.1x EAPoL Tx Done" to Sec FSM. +* +* \param[in] prSta Pointer to the Sta record +* +* \return - +*/ +/*----------------------------------------------------------------------------*/ +VOID +secFsmEventEapolTxDone ( + IN P_ADAPTER_T prAdapter, + IN P_STA_RECORD_T prStaRec, + IN ENUM_TX_RESULT_CODE_T rTxDoneStatus + ) +{ + P_SEC_INFO_T prSecInfo; + ENUM_SEC_STATE_T eNextState; + BOOLEAN fgIsTransition = (BOOLEAN)FALSE; + P_AIS_SPECIFIC_BSS_INFO_T prAisBssInfo; + + DEBUGFUNC("secFsmRunEventEapolTxDone"); + + ASSERT(prStaRec); + + if (rTxDoneStatus != TX_RESULT_SUCCESS) { + DBGLOG(RSN, INFO, ("Error EAPoL fram fail to send!!\n")); + //ASSERT(0); + return; + } + + if (!IS_STA_IN_AIS(prStaRec)) { + DBGLOG(RSN, INFO, ("Counter Measure should occur at AIS network!!\n")); + //ASSERT(0); + return; + } + + prAisBssInfo = &prAdapter->rWifiVar.rAisSpecificBssInfo; + + ASSERT(prAisBssInfo); + + prSecInfo = &prStaRec->rSecInfo; + eNextState = prSecInfo->eCurrentState; + +#if CFG_SUPPORT_XLOG + DBGLOG(RSN, TRACE, (MACSTR " Sec state [%d]\n", MAC2STR(prStaRec->aucMacAddr), prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, TRACE, (MACSTR " Sec state %s\n", MAC2STR(prStaRec->aucMacAddr), + apucDebugSecState[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 CFG_SUPPORT_XLOG + DBGLOG(RSN, TRACE, (MACSTR " Sec state [%d]\n", MAC2STR(prStaRec->aucMacAddr), prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, TRACE, (MACSTR " Sec state %s\n", MAC2STR(prStaRec->aucMacAddr), + apucDebugSecState[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; + } + + return; +}/* 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 UINT_32 u4Parm + ) +{ + P_STA_RECORD_T prStaRec; + + DEBUGFUNC("secFsmRunEventEapolTxTimeout"); + + prStaRec = (P_STA_RECORD_T)u4Parm; + + 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, + UINT_32 u4Parm + ) +{ + 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)u4Parm; + + 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 CFG_SUPPORT_XLOG + DBGLOG(RSN, TRACE, (MACSTR " Sec state [%d]\n", MAC2STR(prSta->aucMacAddr), prSecInfo->eCurrentState)); +#else + DBGLOG(RSN, TRACE, (MACSTR " Sec state %s\n", MAC2STR(prSta->aucMacAddr), + apucDebugSecState[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); + } + + return; +}/* end of secFsmRunEventEndOfCounterMeasure */ +#endif diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/swcr.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/swcr.c new file mode 100755 index 000000000000..41e4e7548c2e --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/swcr.c @@ -0,0 +1,1213 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/swcr.c#2 $ +*/ + +/*! \file "swcr.c" + \brief + +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: swcr.c $ + * + * 01 15 2012 yuche.tsai + * NULL + * Fix wrong basic rate issue. + * + * 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 eddie.chen + * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) + * Fix initialize the prTxCtrol + * + * 11 19 2011 eddie.chen + * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) + * Add xlog for tx + * + * 11 18 2011 eddie.chen + * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) + * Fix xlog format to hex format + * + * 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 + * reform debug formt. + * + * 11 11 2011 tsaiyuan.hsu + * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered + * add txbcn count into xlog. + * + * 11 10 2011 tsaiyuan.hsu + * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered + * add debug counters of ar and bb 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 Xlog for PS. + * + * 11 04 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 Xlog 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 + * + * 06 27 2011 tsaiyuan.hsu + * [WCXRP00000816] [MT6620 Wi-Fi][Driver] add control to enable rx data dump or not + * add control to enable rx data dump by packet type. + * + * 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 Klocwork warning. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +extern SWCR_MAP_ENTRY_T g_arRlmArSwCrMap[]; +SWCR_MOD_MAP_ENTRY_T g_arSwCrAllMaps[] = { + { SWCR_MAP_NUM(g_arRlmArSwCrMap), g_arRlmArSwCrMap}, /* 0x00nn */ + {0,NULL} +}; +#endif + +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 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, + UINT_32 u4Param); +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); + +UINT_32 g_au4SwCr[SWCR_CR_NUM]; /*: 0: command other: data */ + +static TIMER_T g_rSwcrDebugTimer; +static BOOLEAN g_fgSwcrDebugTimer = FALSE; +static UINT_32 g_u4SwcrDebugCheckTimeout = 0; +static ENUM_SWCR_DBG_TYPE_T g_ucSwcrDebugCheckType = 0; +static UINT_32 g_u4SwcrDebugFrameDumpType = 0; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +#define TEST_PS 1 + +const static PFN_CMD_RW_T g_arSwCtrlCmd[] ={ + swCtrlCmdCategory0, + swCtrlCmdCategory1 +#if TEST_PS + , testPsCmdCategory0 + , testPsCmdCategory1 +#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_CATA0_INDEX_NUM +}; + +enum { + SWCTRL_STA_INFO, + SWCTRL_DUMP_STA, + SWCTRL_STA_QUE_INFO, + SWCTRL_CATA1_INDEX_NUM +}; + + + +#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 + + + + + +#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; iau4HeadStaRecIndex[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;jai4TxPendingFrameNumPerQueue[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: " MACSTR " Rcpi %u" "\n", MAC2STR(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; iarTxQueue[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;iaprRxReorderParamRefTbl[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 " MACSTR"\n",MAC2STR(prBssInfo->aucOwnMacAddr))); + DBGLOG(SW4, INFO, ("BSSID " MACSTR"\n",MAC2STR(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;irQM.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 + 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; + } + + } + 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;irQM.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) { + } + 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 */ + if ( (prMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimatedFrameLen)) == 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)((UINT_32)(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)( (PUINT_8)((UINT_32)(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)); + + return; +} + + + + +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); + 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 + + + +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, INFO, ("%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, + (UINT_32) 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, + UINT_32 u4Param) +{ + 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); + + return; +} + +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/mtk_wcn_combo/drv_wlan/wlan/mgmt/wapi.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/wapi.c new file mode 100755 index 000000000000..db2bf3456e1e --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/mgmt/wapi.c @@ -0,0 +1,568 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2009 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER + +* Copyright (c) 2008 MediaTek Inc. ALL RIGHTS RESERVED. + +* BY OPENING OR USING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES +* AND AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS (¡§MEDIATEK +* SOFTWARE¡¨)RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN ¡§AS IS¡¨ BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING +* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. NOR DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTIES +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE. +* BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTIES FOR ANY AND ALL +* WARRANTY CLAIMS RELATING THERETO. MEDIATEK SHALL NOT BE RESPONSIBLE FOR +* ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER¡¦S SPECIFICATION OR CONFORMING +* TO A PARTICULAR STANDARD OR OPEN FORUM. + +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER SHALL BE, +* AT MEDIATEK'S SOLE OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE +* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGES PAID BY BUYER TO +* MEDIATEK FOR SUCH MEDIATEK SOFTWARE. + +* THE MEDIATEK SOFTWARE IS PROVIDED FOR AND ONLY FOR USE WITH MEDIATEK CHIPS +* OR PRODUCTS. EXCEPT AS EXPRESSLY PROVIDED, NO LICENSE IS GRANTED BY +* IMPLICATION OR OTHERWISE UNDER ANY INTELLECTUAL PROPERTY RIGHTS, INCLUDING +* PATENT OR COPYRIGHTS, OF MEDIATEK. UNAUTHORIZED USE, REPRODUCTION, OR +* DISCLOSURE OF THE MEDIATEK SOFTWARE IN WHOLE OR IN PART IS STRICTLY PROHIBITED. + +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE WITH +* THE LAWS OF THE REPUBLIC OF SINGAPORE, EXCLUDING ITS CONFLICT OF LAWS +* PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS RELATING HERETO OR ARISING +* HEREFROM SHALL BE EXCLUSIVELY SETTLED VIA ARBITRATION IN SINGAPORE UNDER THE +* THEN CURRENT ARBITRAL RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE. +* THE LANGUAGE OF ARBITRATION SHALL BE ENGLISH. THE AWARDS OF THE ARBITRATION +* SHALL BE FINAL AND BINDING UPON BOTH PARTIES AND SHALL BE ENTERED AND +* ENFORCEABLE IN ANY COURT OF COMPETENT JURISDICTION. +******************************************************************************** +*/ + +/* +** $Log: wapi.c $ + * + * 11 10 2011 wh.su + * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG + * change the debug module level. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 Microsoft 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)((UINT_32)prMsduInfo->prPacket + + (UINT_32)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_CIPHER_SUITES) { + u2PairSuiteCount = MAX_NUM_SUPPORTED_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_AKM_SUITES) { + u2AuthSuiteCount = MAX_NUM_SUPPORTED_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; + } + else { + 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%08lx/0x%08lx)\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/mtk_wcn_combo/drv_wlan/wlan/nic/cmd_buf.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/cmd_buf.c new file mode 100755 index 000000000000..c5d7cacace2f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/cmd_buf.c @@ -0,0 +1,262 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: cmd_buf.c $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +******************************************************************************** +*/ + +/******************************************************************************* +* M A 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); + } + +} /* end of cmdBufInitialize() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + } + else { + prCmdInfo->u2InfoBufLen = 0; + prCmdInfo->fgIsOid = FALSE; + prCmdInfo->fgDriverDomainMCR = FALSE; + } + } + + 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/mtk_wcn_combo/drv_wlan/wlan/nic/nic.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic.c new file mode 100755 index 000000000000..10ab7c7009b0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic.c @@ -0,0 +1,4370 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/nic/nic.c#3 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic.c $ + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 01 13 2012 yuche.tsai + * NULL + * Update driver/p2p driver for ICS tethering mode. + * Fix FW reply probe request issue. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 + * Add P2P RSSI Link Quality Query Support. (Default Off) + * + * 11 04 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 Xlog 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 freeing 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 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * Support TX Deauth while tearing down a station connection. + * + * 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 11 2011 eddie.chen + * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet + * Fix dest type when GO packet copying. + * + * 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 + * sync. whole-chip resetting mechanism to V2.0 branch. + * + * 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 after WLAN module removed. + * + * 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 07 2011 eddie.chen + * [WCXRP00000527] [MT6620 Wi-Fi][FW/Driver] Clean buffered packet when BSS is inactive or disconnected[WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma + * Remove packet when BSS is inactive + * + * 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 similiar 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 continous memory demands + * 1) correct typo in scan.c + * 2) TX descriptors, RX descriptos and management buffer should use virtually continous 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 occured + * + * 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(INIT, INFO, ("Allocating %ld bytes for %s.\n", u4Size, pucComment)); \ + if ((pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType)) == (PUINT_8)NULL) { \ + DBGLOG(INIT, ERROR, ("Could not allocate %ld bytes for %s.\n", u4Size, pucComment)); \ + break; \ + } \ + ASSERT(((UINT_32)pucMem % 4) == 0); \ + DBGLOG(INIT, INFO, ("Virtual Address = %08lx for %s.\n", (UINT_32)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 +******************************************************************************** +*/ + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief This routine is responsible for the allocation of the data structures +* inside the Adapter structure, include: +* 1. SW_RFB_Ts +* 2. Common coalescing buffer for TX PATH. +* +* @param prAdapter Pointer of Adapter Data Structure +* +* @retval WLAN_STATUS_SUCCESS - Has enough memory. +* @retval WLAN_STATUS_RESOURCES - Memory is not enough. +*/ +/*----------------------------------------------------------------------------*/ +WLAN_STATUS +nicAllocateAdapterMemory ( + IN P_ADAPTER_T prAdapter + ) +{ + WLAN_STATUS status = WLAN_STATUS_RESOURCES; + P_RX_CTRL_T prRxCtrl; + P_TX_CTRL_T prTxCtrl; + + DEBUGFUNC("nicAllocateAdapterMemory"); + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + prTxCtrl = &prAdapter->rTxCtrl; + + do { + //4 <0> Reset all Memory Handler + #if CFG_DBG_MGT_BUF + prAdapter->u4MemFreeDynamicCount = 0; + prAdapter->u4MemAllocDynamicCount = 0; + #endif + prAdapter->pucMgtBufCached = (PUINT_8)NULL; + prRxCtrl->pucRxCached = (PUINT_8)NULL; + prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T)NULL; + + + //4 <1> Memory for Management Memory Pool and CMD_INFO_T + /* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */ + prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE; + + LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached, + prAdapter->u4MgtBufCachedSize, + VIR_MEM_TYPE, + "COMMON MGMT MEMORY POOL"); + + //4 <2> Memory for RX Descriptor + /* Initialize the number of rx buffers we will have in our queue. */ + /* We may setup ucRxPacketDescriptors by GLUE Layer, and using + * this variable directly. + */ + /* Allocate memory for the SW receive structures. */ + prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * \ + ALIGN_4(sizeof(SW_RFB_T)); + + LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached, + prRxCtrl->u4RxCachedSize, + VIR_MEM_TYPE, + "SW_RFB_T"); + + //4 <3> Memory for TX DEscriptor + prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * \ + ALIGN_4(sizeof(MSDU_INFO_T)); + + LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached, + prTxCtrl->u4TxCachedSize, + VIR_MEM_TYPE, + "MSDU_INFO_T"); + + //4 <4> Memory for Common Coalescing Buffer +#if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG + prAdapter->pucCoalescingBufCached = (PUINT_8)NULL; + + /* Allocate memory for the common coalescing buffer. */ + prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ? + CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE; + + prAdapter->pucCoalescingBufCached = + kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize); + + if(prAdapter->pucCoalescingBufCached == NULL) { + DBGLOG(INIT, ERROR, ("Could not allocate %ld 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(INIT, ERROR, ("Could not allocate %ld 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 + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @brief disable global interrupt +* +* @param prAdapter pointer to the Adapter handler +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +VOID +nicDisableInterrupt ( + IN P_ADAPTER_T prAdapter + ) +{ + ASSERT(prAdapter); + + HAL_BYTE_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_BYTE_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET); + } + + return; +} /* 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( (UINT_32)&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 = 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; + + return; +} /* 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(INIT, 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++) { + +#if CFG_SDIO_INTR_ENHANCE + nicSDIOReadIntStatus(prAdapter, &u4IntStatus); +#else + HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus); +#endif /* CFG_SDIO_INTR_ENHANCE */ + + //DBGLOG(INIT, 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", + (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus, 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#: %ld, event:%d, func: 0x%x\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 +*/ +/*----------------------------------------------------------------------------*/ +BOOL +nicVerifyChipID ( + IN P_ADAPTER_T prAdapter + ) +{ + UINT_32 u4CIR = 0; + + ASSERT(prAdapter); + + HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR ); + + DBGLOG(INIT, TRACE,("Chip ID: 0x%x\n", u4CIR & WCIR_CHIP_ID)); + DBGLOG(INIT, TRACE,("Revision ID: 0x%x\n", ((u4CIR & WCIR_REVISION_ID) >> 16))); + + if ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV) { + return FALSE; + } + + 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; + + 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 + ) +{ + + return; +} /* end of nicProcessFwOwnBackInterrupt() */ + +/*----------------------------------------------------------------------------*/ +/*! +* @brief . +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +VOID +nicProcessSoftwareInterrupt( + IN P_ADAPTER_T prAdapter + ) +{ + UINT_32 u4IntrBits; + + ASSERT(prAdapter); + + u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31); + + 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)); + + return; +} /* end of nicProcessSoftwareInterrupt() */ + +VOID +nicPutMailbox ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4MailboxNum, + IN UINT_32 u4Data + ) +{ + if (u4MailboxNum == 0) { + HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data); + } else if (u4MailboxNum == 1) { + 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(prAdapter, MCR_D2HRM0R, pu4Data); + } else if (u4MailboxNum == 1) { + HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data); + } else { + ASSERT(0); + } +} + +VOID +nicSetSwIntr ( + IN P_ADAPTER_T prAdapter, + IN UINT_32 u4SwIntrBitmap + ) +{ + /* NOTE: + * SW interrup 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(INIT, 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; + else { + 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; + 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); + + 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(); + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST); + do { + if (prAdapter == NULL) { + + ASSERT(FALSE); + break; + } + + 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) { + + 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) + kalIndicateStatusAndComplete(prGlueInfo, + WLAN_STATUS_MEDIA_CONNECT, + 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; + 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); + DBGLOG(INIT, LOUD, ("nicUpdateBss\n")); + 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; +#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 (prAdapter->rP2pFuncLkr.prKalP2pGetCipher && + prAdapter->rP2pFuncLkr.prKalP2pGetCipher(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; + } + rCmdSetBssInfo.fgIsApMode = prAdapter->rP2pFuncLkr.prP2pFuncIsApMode(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 = 0; + } + + DBGLOG(REQ, TRACE, ("SET_BSS_INFO auth=%d, enc=%d\n", rCmdSetBssInfo.ucAuthMode, rCmdSetBssInfo.ucEncStatus)); + + + 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); + DBGLOG(INIT, LOUD, ("free all correlated station records\n")); + } + + 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(INIT, 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, + TRUE, + (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() */ + +/*----------------------------------------------------------------------------*/ +/*! +* @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(INIT, LOUD, ("\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(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 = 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); + DBGLOG(INIT, LOUD, ("Command ID = 0x%08X\n", prCmdInfo->ucCID)); + 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; + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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): %d \n", sizeof(AC_QUE_PARMS_T))); + DBGLOG(QM, EVENT, ("sizeof(CMD_UPDATE_WMM_PARMS): %d \n", sizeof(CMD_UPDATE_WMM_PARMS_T))); + DBGLOG(QM, EVENT, ("sizeof(WIFI_CMD_T): %d \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 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); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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 */ + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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); + + return; +} + + +#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; + } + else { + 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; + } + else { + 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)((UINT_32)(prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize); + + u4ReserveSize = ((UINT_32)pucPivot) - (UINT_32)(&(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)((UINT_32)(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; + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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(INIT, INFO, ("ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3)); + DBGLOG(INIT, INFO, ("ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer)); + DBGLOG(INIT, INFO, ("HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask)); + DBGLOG(INIT, 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(MT5931) + u4ChipId = 5931; +#elif defined(MT6628) + u4ChipId = 6628; +#endif + + kalPrint("\n[MT%ld][wifi][Firmware] Assert at \"%s\" #%ld\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: + /* 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 +#if 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 +#endif + default: + break; + + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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: + 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; + + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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: + /* buffer statistics for further query */ + prAdapter->fgIsLinkRateValid = TRUE; + prAdapter->rLinkRateUpdateTime = kalGetTimeTick(); + + prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed; + + break; + + default: + break; + + } + + return; +} + +#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/mtk_wcn_combo/drv_wlan/wlan/nic/nic_cmd_event.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_cmd_event.c new file mode 100755 index 000000000000..ffeeac036736 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_cmd_event.c @@ -0,0 +1,1588 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic_cmd_event.c $ + * + * 01 27 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Fix compile warning & update latest driver 2.2. + * Davinci Label: 20120127_ALPS_WIFI_P2P_DRIVER_V2_1 + * + * 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 microsoft 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_STRUC_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_STRUC_T); + + prMcrRdInfo = (P_PARAM_CUSTOM_MCR_RW_STRUC_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_STRUC_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_STRUC_T); + + prSwCtrlInfo = (P_PARAM_CUSTOM_SW_CTRL_STRUC_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 Infomation Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4InformationBufferLength, + WLAN_STATUS_SUCCESS); + } + + return; +} + +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 Infomation Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, + WLAN_STATUS_SUCCESS); + } + + kalIndicateStatusAndComplete(prAdapter->prGlueInfo, + WLAN_STATUS_MEDIA_DISCONNECT, + NULL, + 0); + +#if !defined(LINUX) + prAdapter->fgIsRadioOff = TRUE; +#endif + + return; +} + +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 Infomation 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); + } + + return; +} + +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 Infomation Length */ + kalOidComplete(prGlueInfo, + prCmdInfo->fgSetQuery, + u4QueryInfoLen, + WLAN_STATUS_SUCCESS); + } + + return; +} + +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 + + 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; + + 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); + + if(prLinkQuality->u2LinkSpeed == 0) { + *pu4LinkSpeed = 10000; /* 10K * 100bps = 1Mbps */ + } + else { + *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 + ) +{ + UINT_32 u4WHISR = 0, u4Value = 0; + UINT_8 aucTxCount[8]; + + 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) { + if (prCmdInfo->fgIsOid) { + /* Update Set Infomation Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + WLAN_STATUS_NOT_SUPPORTED); + + } + return; + } + else + kalMsleep(10); + } + + // 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 Infomation 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 + + return; +} + +VOID +nicCmdEventLeaveRfTest( + IN P_ADAPTER_T prAdapter, + IN P_CMD_INFO_T prCmdInfo, + IN PUINT_8 pucEventBuf + ) +{ + UINT_32 u4WHISR = 0, u4Value = 0; + UINT_8 aucTxCount[8]; + + 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) { + if (prCmdInfo->fgIsOid) { + /* Update Set Infomation Length */ + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + prCmdInfo->u4SetInfoLen, + WLAN_STATUS_NOT_SUPPORTED); + + } + return; + } + else { + kalMsleep(10); + } + } + + // 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 Infomation 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); + + return; +} + +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); + + return; +} + +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_STRUC_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_STRUC_T); + + prEepromRdInfo = (P_PARAM_CUSTOM_EEPROM_RW_STRUC_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 Infomation 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. indiate for OID failure + kalOidComplete(prAdapter->prGlueInfo, + prCmdInfo->fgSetQuery, + 0, + WLAN_STATUS_FAILURE); +} + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_pwr_mgt.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_pwr_mgt.c new file mode 100755 index 000000000000..24f3b60a7d8f --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_pwr_mgt.c @@ -0,0 +1,825 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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; + + ASSERT(prAdapter); + + if(prAdapter->fgIsFwOwn == TRUE) { + return; + } + else { + 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) +*/ +/*----------------------------------------------------------------------------*/ +BOOLEAN +nicpmSetDriverOwn ( + IN P_ADAPTER_T prAdapter + ) +{ +#define LP_OWN_BACK_TOTAL_DELAY_MS 8192 //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, u4RegValue = 0; + + ASSERT(prAdapter); + + if(prAdapter->fgIsFwOwn == FALSE) + return fgStatus; + + u4CurrTick = kalGetTimeTick(); + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_WHLPCR, &u4RegValue); + + if (u4RegValue & WHLPCR_FW_OWN_REQ_SET) { + prAdapter->fgIsFwOwn = FALSE; + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE + || (kalGetTimeTick() - u4CurrTick) > LP_OWN_BACK_TOTAL_DELAY_MS) { + //ERRORLOG(("LP cannot be own back (for %ld ms)", kalGetTimeTick() - u4CurrTick)); + fgStatus = FALSE; + break; + } + else { + 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++; + } + } + + 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; + +#if defined(MT6620) || defined(MT6628) + /* 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 */ + if ( (u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS ) { + DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } +#endif + + #if CFG_ENABLE_FW_DOWNLOAD + prFwMappingHandle = kalFirmwareImageMapping(prAdapter->prGlueInfo, &pvFwImageMapFile, &u4FwImgLength); + if(!prFwMappingHandle) { + DBGLOG(INIT, ERROR,("Fail to load FW image from file!\n")); + pvFwImageMapFile = NULL; + } + + #if defined(MT6620) || defined(MT6628) + if (pvFwImageMapFile) { + /* 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(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!\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(INIT, 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(INIT, 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); + } + else { + u4Status = WLAN_STATUS_FAILURE; + break; + } + + /* 4. send Wi-Fi Start command */ + #if CFG_OVERRIDE_FW_START_ADDRESS + wlanConfigWifiFunc(prAdapter, + TRUE, + kalGetFwStartAddress(prAdapter->prGlueInfo)); + #else + wlanConfigWifiFunc(prAdapter, + FALSE, + 0); + #endif + + #elif defined(MT5931) + if (pvFwImageMapFile) { + DBGLOG(INIT, TRACE, ("Download Address: 0x%08X\n", kalGetFwLoadAddress(prAdapter->prGlueInfo))); + DBGLOG(INIT, TRACE, ("Firmware Length: 0x%08X\n", u4FwImgLength)); + + do { + /* 1.0 whole-chip reset except HIFSYS */ + HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_CHIP_RST); + HAL_MCR_WR(prAdapter, MCR_WMCSR, 0); + + /* 1.1 wait for INIT_RDY */ + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); + + if (u4Value & WMCSR_INI_RDY) { + DBGLOG(INIT, TRACE, ("INIT-RDY detected\n")); + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for Init Ready bit: Timeout\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + + /* 1.2 set KSEL/FLEN */ + HAL_MCR_WR(prAdapter, MCR_FWCFG, u4FwImgLength >> 6); + + /* 1.3 enable FWDL_EN */ + HAL_MCR_WR(prAdapter, MCR_WMCSR, WMCSR_FWDLEN); + + /* 1.4 wait for PLL_RDY */ + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); + + if (u4Value & WMCSR_PLLRDY) { + DBGLOG(INIT, TRACE, ("PLL-RDY detected\n")); + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE) { + u4Status = WLAN_STATUS_FAILURE; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for PLL Ready bit: Timeout\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + + /* 2.1 turn on HIFSYS firmware download mode */ + HAL_MCR_WR(prAdapter, MCR_FWDLSR, FWDLSR_FWDL_MODE); + + /* 2.2 set starting address */ + u4FwLoadAddr = kalGetFwLoadAddress(prAdapter->prGlueInfo); + HAL_MCR_WR(prAdapter, MCR_FWDLDSAR, u4FwLoadAddr); + + /* 3. upload firmware */ + 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(INIT, ERROR, ("Firmware scatter download failed!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + } + + /* 4.1 poll FWDL_OK & FWDL_FAIL bits */ + i = 0; + while(1) { + HAL_MCR_RD(prAdapter, MCR_WMCSR, &u4Value); + + if (u4Value & WMCSR_DL_OK) { + DBGLOG(INIT, TRACE, ("DL_OK detected\n")); + break; + } + else if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE + || fgIsBusAccessFailed == TRUE + || (u4Value & WMCSR_DL_FAIL)) { + DBGLOG(INIT, ERROR, ("DL_FAIL detected: 0x%08X\n", u4Value)); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for DL_OK/DL_FAIL bit: Timeout\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + + /* 4.2 turn off HIFSYS download mode */ + HAL_MCR_WR(prAdapter, MCR_FWDLSR, 0); + + } while (FALSE); + } + else { + DBGLOG(INIT, ERROR, ("No Firmware found!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + + #endif + #endif + + /* 5. check Wi-Fi FW asserts ready bit */ + DBGLOG(INIT, TRACE, ("wlanAdapterStart(): Waiting for Ready bit..\n")); + 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; + break; + } + else if(i >= CFG_RESPONSE_POLLING_TIMEOUT) { + DBGLOG(INIT, ERROR, ("Waiting for Ready bit: Timeout\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } + else { + i++; + kalMsleep(10); + } + } + +#if defined(MT5931) + // Acquire LP-OWN + ACQUIRE_POWER_CONTROL_FROM_PM(prAdapter); + #if !CFG_ENABLE_FULL_PM + nicpmSetDriverOwn(prAdapter); + #endif + + /* 2. Initialize the Adapter */ + if ( (u4Status = nicInitializeAdapter(prAdapter)) != WLAN_STATUS_SUCCESS ) { + DBGLOG(INIT, ERROR, ("nicInitializeAdapter failed!\n")); + u4Status = WLAN_STATUS_FAILURE; + break; + } +#endif + + 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/mtk_wcn_combo/drv_wlan/wlan/nic/nic_rx.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_rx.c new file mode 100755 index 000000000000..10fdceff1673 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_rx.c @@ -0,0 +1,3568 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic_rx.c $ + * + * 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 19 2011 yuche.tsai + * NULL + * Add P2P RSSI Link Quality Query Support. (Default 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 04 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 Xlog debugging. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * + * 06 27 2011 tsaiyuan.hsu + * [WCXRP00000816] [MT6620 Wi-Fi][Driver] add control to enable rx data dump or not + * add control to enable rx data dump by packet type. + * + * 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 16 2011 eddie.chen + * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet + * Sync from ALPS. + * + * 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 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 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Add device discoverability support. (Phase I) + * + * 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 Netwrok. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 LENTH field is 1 byte +** \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426 +** Update RX OOB Setting +** \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426 +** Fixed logical error +** \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461 +** Rename the HIF_PKT_TYPE_DATA +** \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461 +** Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket() +** \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426 +** Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support +** \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426 +** Add nicRxWaitResponse function +** \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426 +** Init for develop +** +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "precomp.h" + +#ifndef LINUX +#include +#else +#include +#endif + +/******************************************************************************* +* 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 + 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((UINT_32)(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; + #if !defined(MT5931) + HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM); + #endif +#else + #if !defined(MT5931) + HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1); + #endif +#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 + + return; +} /* end of nicRxInitialize() */ + + +#if defined(MT5931) +/*----------------------------------------------------------------------------*/ +/*! +* @brief Initialize HIF RX control registers explicitly +* +* @param prAdapter Pointer to the Adapter structure. +* +* @return (none) +*/ +/*----------------------------------------------------------------------------*/ +VOID +nicRxPostInitialize ( + IN P_ADAPTER_T prAdapter + ) +{ + P_RX_CTRL_T prRxCtrl; + DEBUGFUNC("nicRxPostInitialize"); + + ASSERT(prAdapter); + prRxCtrl = &prAdapter->rRxCtrl; + +#if CFG_SDIO_RX_AGG + 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 + +} /* end of nicRxPostInitialize() */ +#endif + + +/*----------------------------------------------------------------------------*/ +/*! +* @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); + + return; +} /* 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; + BOOL 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 availble 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; + } + else { + 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 + } + 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); + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + + DEBUGFUNC("nicRxProcessDataPacket"); + //DBGLOG(INIT, TRACE, ("\n")); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prHifRxHdr = prSwRfb->prHifRxHdr; + prRxCtrl = &prAdapter->rRxCtrl; + + nicRxFillRFB(prAdapter, prSwRfb); + +#if 1 /* Check 1x Pkt */ + if (prSwRfb->u2PacketLen > 14) { + PUINT_8 pc = (PUINT_8)prSwRfb->pvHeader; + UINT_16 u2Etype = 0; + + u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]); + +#if CFG_SUPPORT_WAPI + if (u2Etype == ETH_P_1X || u2Etype == ETH_WPI_1X) { + DBGLOG(RSN, INFO, ("R1X len=%d\n", prSwRfb->u2PacketLen)); + } +#else + if (u2Etype == ETH_P_1X) { + DBGLOG(RSN, INFO, ("R1X len=%d\n", prSwRfb->u2PacketLen)); + } +#endif + else if (u2Etype == ETH_P_PRE_1X) { + DBGLOG(RSN, INFO, ("Pre R1X len=%d\n", prSwRfb->u2PacketLen)); + } + } +#endif + +#if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60 + { + UINT_32 u4TcpUdpIpCksStatus; + + u4TcpUdpIpCksStatus = *((PUINT_32)((UINT_32)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 + + if((prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb)) != NULL) { + do { + // save next first + prNextSwRfb = (P_SW_RFB_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prRetSwRfb); + + switch(prRetSwRfb->eDst) { + case RX_PKT_DESTINATION_HOST: + 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) +* +*/ +/*----------------------------------------------------------------------------*/ +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"); + //DBGLOG(INIT, TRACE, ("\n")); + + ASSERT(prAdapter); + ASSERT(prSwRfb); + + prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff; + prGlueInfo = prAdapter->prGlueInfo; + + // 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); + + 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; + + 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, INFO, ("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:["MACSTR"]\n", + prActivateStaRec->ucStaRecIdx, + MAC2STR(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:["MACSTR"]\n", + prDeactivateStaRec->ucStaRecIdx); + + 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: + { + P_EVENT_TX_DONE_T prTxDone; + prTxDone = (P_EVENT_TX_DONE_T)(prEvent->aucBuffer); + + DBGLOG(INIT, TRACE,("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(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: + DBGLOG(INIT, INFO,("EVENT_ID_BSS_BEACON_TIMEOUT\n")); + + if (prAdapter->fgDisBcnLostDetection == FALSE) { + P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout; + prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T)(prEvent->aucBuffer); + + if(prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) { + aisBssBeaconTimeout(prAdapter); + } +#if CFG_ENABLE_WIFI_DIRECT + else if((prAdapter->fgIsP2PRegistered) && + (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) { + + prAdapter->rP2pFuncLkr.prP2pFsmRunEventBeaconTimeout(prAdapter); + } +#endif +#if CFG_ENABLE_BT_OVER_WIFI + else if(prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) { + } +#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) { + prAdapter->rP2pFuncLkr.prP2pProcessEvent_UpdateNOAParam(prAdapter, + prEventUpdateNoaParam->ucNetTypeIndex, + prEventUpdateNoaParam); + } else { + ASSERT(0); + } + } +#else + ASSERT(0); +#endif + break; + + case EVENT_ID_STA_AGING_TIMEOUT: +#if CFG_ENABLE_WIFI_DIRECT + { + 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(INIT, INFO,("EVENT_ID_STA_AGING_TIMEOUT %u " MACSTR "\n", + prEventStaAgingTimeout->ucStaRecIdx, MAC2STR(prStaRec->aucMacAddr))); + prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]); + + /* Call False Auth */ + if(prAdapter->fgIsP2PRegistered){ + if(prAdapter->rP2pFuncLkr.prP2pFuncDisconnect) { + prAdapter->rP2pFuncLkr.prP2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY); + } + } + + bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec); + } +#endif + break; + + case EVENT_ID_AP_OBSS_STATUS: +#if CFG_ENABLE_WIFI_DIRECT + if(prAdapter->fgIsP2PRegistered){ + ASSERT(prAdapter->rP2pFuncLkr.prRlmHandleObssStatusEventPkt); + prAdapter->rP2pFuncLkr.prRlmHandleObssStatusEventPkt( + 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; +#if 0 // CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_ANTI_PIRACY + case EVENT_ID_SEC_CHECK_RSP: + if(prAdapter->fgIsP2PRegistered){ + ASSERT(prAdapter->rP2pFuncLkr.prP2pHandleSecCheckRsp); + + prAdapter->rP2pFuncLkr.prP2pHandleSecCheckRsp( + prAdapter, + (PUINT_8) prEvent->aucBuffer, + prEvent->u2PacketLen - EVENT_HDR_SIZE); + + /* 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 + case EVENT_ID_SEND_DEAUTH: +#if DBG + { + P_WLAN_MAC_HEADER_T prWlanMacHeader; + + prWlanMacHeader = (P_WLAN_MAC_HEADER_T)&prEvent->aucBuffer[0]; + DBGLOG(RX, INFO, ("nicRx: aucAddr1: "MACSTR"\n", MAC2STR(prWlanMacHeader->aucAddr1))); + DBGLOG(RX, INFO, ("nicRx: aucAddr2: "MACSTR"\n", MAC2STR(prWlanMacHeader->aucAddr2))); + } +#endif + /* 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(RX, INFO, ("Send Deauth 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 + printk(KERN_INFO DRV_NAME "BCM BWCS Event: %02x%02x%02x%02x\n", prEventBwcsStatus->u.aucBTPParams[0], + prEventBwcsStatus->u.aucBTPParams[1], + prEventBwcsStatus->u.aucBTPParams[2], + prEventBwcsStatus->u.aucBTPParams[3]); + + printk(KERN_INFO DRV_NAME "BCM BWCS Event: aucBTPParams[0] = %02x, aucBTPParams[1] = %02x, aucBTPParams[2] = %02x, aucBTPParams[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 + printk(KERN_INFO DRV_NAME "BCM FW status: %02x%02x%02x%02x\n", prEventBwcsStatus->u.aucBTPParams[0], + prEventBwcsStatus->u.aucBTPParams[1], + prEventBwcsStatus->u.aucBTPParams[2], + prEventBwcsStatus->u.aucBTPParams[3]); + + printk(KERN_INFO DRV_NAME "BCM FW status: aucBTPParams[0] = %02x, aucBTPParams[1] = %02x, aucBTPParams[2] = %02x, aucBTPParams[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_ACCESS_REG: + case EVENT_ID_NIC_CAPABILITY: + case EVENT_ID_BASIC_CONFIG: + case EVENT_ID_MAC_MCAST_ADDR: + case EVENT_ID_ACCESS_EEPROM: + case EVENT_ID_TEST_STATUS: + 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 + BOOL fgMfgDrop = FALSE; +#endif + ASSERT(prAdapter); + ASSERT(prSwRfb); + + nicRxFillRFB(prAdapter, prSwRfb); + + ucSubtype = (*(PUINT_8)(prSwRfb->pvHeader) & MASK_FC_SUBTYPE )>> OFFSET_OF_FC_SUBTYPE; + +#if 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(SW4, INFO, ("QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n", + HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), + prHifRxHdr->ucStaRecIdx, + prSwRfb->ucWlanIdx, + 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) { +#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; + } + else +#endif + if(apfnProcessRxMgtFrame[ucSubtype]) { + switch(apfnProcessRxMgtFrame[ucSubtype](prAdapter, prSwRfb)){ + case WLAN_STATUS_PENDING: + return; + case WLAN_STATUS_SUCCESS: + case WLAN_STATUS_FAILURE: + break; + + default: + ASSERT(0); + break; + } + } +#endif + } + + nicRxReturnRFB(prAdapter, prSwRfb); +} + +/*----------------------------------------------------------------------------*/ +/*! +* @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){ + 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: + DBGLOG(RX, ERROR, ("ucPacketType = %d\n", prSwRfb->ucPacketType)); + 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)); + 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; + BOOL 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)((UINT_32)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 (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW)); + while (FALSE); + + 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; + BOOL 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 = %d\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 (%d)\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(prAdapter, &u2RxLength, &u2Tmp); + } + else if(rxNum == 1) { + 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; + + return; +}/* 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; + BOOL 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)); + + 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); + + return; +} +#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(&prRxCtrl->rFreeSwRfbList, prQueEntry); + } + else { + QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry); + } + + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE); + return; +} /* 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 + ) +{ + ASSERT(prAdapter); + +#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) { + 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); + } + + return; +} /* 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 :%9ld", prRxCtrl->rFreeSwRfbList.u4NumElem)); + SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9ld", prRxCtrl->rIndicatedRfbList.u4NumElem)); + SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST :%9ld", prRxCtrl->rReceivedRfbList.u4NumElem)); + + SPRINTF(pucCurrBuf, ("\n\n")); + + //*pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer); + + return; +} /* 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); + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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 : %ld\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); + + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* @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, i = 0; + WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS; + BOOL fgResult = TRUE; + UINT_32 u4Time, u4Current; + + DEBUGFUNC("nicRxWaitResponse"); + + ASSERT(prAdapter); + ASSERT(pucRspBuffer); + ASSERT(ucPortIdx < 2); + + u4Time = (UINT_32)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 = (UINT_32)kalGetTimeTick(); + + if((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) { + return WLAN_STATUS_FAILURE; + } + else if(u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) { + return WLAN_STATUS_FAILURE; + } + + /* Response packet is not ready */ + kalUdelay(50); + + i++; + } + else if (u4PktLen > u4MaxRespBufferLen) { + DBGLOG(RX, WARN, ("Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n", + u4PktLen, u4MaxRespBufferLen)); + + return WLAN_STATUS_FAILURE; + } + else { + 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); + + return; +} /* 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); + + return; +} /* 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); + + if((prSwRfb = qmFlushRxQueues(prAdapter)) != 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; + + switch (prActFrame->ucCategory) { + case CATEGORY_PUBLIC_ACTION: + + #if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prRlmProcessPublicAction); + if (prAdapter->rP2pFuncLkr.prRlmProcessPublicAction) { + prAdapter->rP2pFuncLkr.prRlmProcessPublicAction( + prAdapter, prSwRfb); + } + + ASSERT(prAdapter->rP2pFuncLkr.prP2pRxPublicActionFrame); + if (prAdapter->rP2pFuncLkr.prP2pRxPublicActionFrame) { + prAdapter->rP2pFuncLkr.prP2pRxPublicActionFrame( + prAdapter, prSwRfb); + } + } + #endif + break; + + case CATEGORY_HT_ACTION: + #if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prRlmProcessHtAction); + if (prAdapter->rP2pFuncLkr.prRlmProcessHtAction) { + prAdapter->rP2pFuncLkr.prRlmProcessHtAction( + prAdapter, prSwRfb); + } + } + #endif + break; + case CATEGORY_VENDOR_SPECIFIC_ACTION: + #if CFG_ENABLE_WIFI_DIRECT + if (prAdapter->fgIsP2PRegistered) { + ASSERT(prAdapter->rP2pFuncLkr.prP2pRxActionFrame); + if (prAdapter->rP2pFuncLkr.prP2pRxActionFrame) { + + prAdapter->rP2pFuncLkr.prP2pRxActionFrame(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 + default: + break; + } /* end of switch case */ + + return WLAN_STATUS_SUCCESS; +} + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_tx.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_tx.c new file mode 100755 index 000000000000..06fcde225e3d --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/nic_tx.c @@ -0,0 +1,2020 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: nic_tx.c $ + * + * 03 26 2012 yuche.tsai + * [ALPS00255551] [WiFi direct][Google Issue]GC can't send picture to GO sometimes,GO and GC can't ping each other + * Avoid ran out of driver resource when starting GO. + * + * 11 19 2011 eddie.chen + * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) + * Add xlog 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 availble 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 refering 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); + + return; +} /* 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. +*/ +/*----------------------------------------------------------------------------*/ +WLAN_STATUS +nicTxAcquireResource ( + IN P_ADAPTER_T prAdapter, + IN UINT_8 ucTC + ) +{ + P_TX_CTRL_T prTxCtrl; + WLAN_STATUS u4Status = WLAN_STATUS_RESOURCES; + KAL_SPIN_LOCK_DECLARATION(); + + ASSERT(prAdapter); + prTxCtrl = &prAdapter->rTxCtrl; + + + KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + +// DbgPrint("nicTxAcquireResource prTxCtrl->rTc.aucFreeBufferCount[%d]=%d\n", ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC]); + + if (prTxCtrl->rTc.aucFreeBufferCount[ucTC]) { + + prTxCtrl->rTc.aucFreeBufferCount[ucTC]--; + + DBGLOG(TX, EVENT, ("Acquire: TC = %d aucFreeBufferCount = %d\n", + ucTC, prTxCtrl->rTc.aucFreeBufferCount[ucTC])); + + u4Status = WLAN_STATUS_SUCCESS; + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); + + 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; + } + else { + kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); + } + } + else { + kalMsleep(NIC_TX_RESOURCE_POLLING_DELAY_MSEC); + } + } + +#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 UINT_8* aucTxRlsCnt + ) +{ + PUINT_32 pu4Tmp = (PUINT_32)aucTxRlsCnt; + P_TX_CTRL_T prTxCtrl; + BOOLEAN bStatus = FALSE; + UINT_32 i; + + KAL_SPIN_LOCK_DECLARATION(); + + + ASSERT(prAdapter); + 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]; + + if ((i==1) || (i==5)){ + DBGLOG(TX, EVENT, ("Release: i = %d aucFreeBufferCount = %d\n", + i, prTxCtrl->rTc.aucFreeBufferCount[i])); + } + } + KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_RESOURCE); +#if 0 + for (i = 0; i < TC_NUM; i++) { + DBGLOG(INIT, 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; + + 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: " MACSTR "\n", + MAC2STR(prMsduInfo->aucEthDestAddr)); +#endif + + 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); + 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); + + status = nicTxAcquireResource(prAdapter, prMsduInfo->ucTC); + ASSERT(status == WLAN_STATUS_SUCCESS) + + break; + + default: + ASSERT(0); + break; + } + + prMsduInfo = prNextMsduInfo; + } + + if(qDataPort0.u4NumElem > 0) { + nicTxMsduQueue(prAdapter, 0, &qDataPort0); + } + + if(qDataPort1.u4NumElem > 0) { + nicTxMsduQueue(prAdapter, 1, &qDataPort1); + } + + return WLAN_STATUS_SUCCESS; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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) { + + 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); + + 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->fgIsBIP) { + rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BIP; + } + + if(prMsduInfo->fgIsBasicRate) { + rHwTxHeader.ucAck_BIP_BasicRate |= HIF_TX_HDR_BASIC_RATE; + } + +#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(INIT, 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 + + // return + nicTxReturnMsduInfo(prAdapter, (P_MSDU_INFO_T)QUEUE_GET_HEAD(&rFreeQueue)); + } + + 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; + } + + 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 = 0; + + // <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(INIT, 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); + } + + // <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); + ASSERT(prMsduInfo->pfTxDoneHandler != NULL); + + // invoke done handler + prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_LIFE_TIMEOUT); + + cnmMgtPktFree(prAdapter, prMsduInfo); + } + else { + break; + } + } while(TRUE); + + return; +} /* 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 */ + + ASSERT(prAdapter); + + prTxCtrl = &prAdapter->rTxCtrl; + ASSERT(prTxCtrl); + + /* 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); + } + + return; +} /* 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) { + if (prMsduInfo->pfTxDoneHandler) { + prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, TX_RESULT_DROPPED_IN_DRIVER); + } + cnmMemFree(prAdapter, prNativePacket); + } + 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); + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + } + + 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; + }; + + return; +} + + + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + + + ASSERT(prAdapter); + + prGlueInfo = prAdapter->prGlueInfo; + ASSERT(prGlueInfo); + + if (kalQoSFrameClassifierAndPacketInfo(prGlueInfo, + prPacket, + &ucPriorityParam, + &u4PacketLen, + aucEthDestAddr, + &fgIs1x, + &fgIsPAL, + &ucNetworkType) == FALSE) { + return FALSE; + } + + /* 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); + + 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]; + + ASSERT(prTxCtrl->rTc.aucFreeBufferCount[u4Num] >= 0); + ASSERT(prTxCtrl->rTc.aucMaxNumOfBuffer[u4Num] >= 0); + } + + 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 maintainance 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 */ + 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/mtk_wcn_combo/drv_wlan/wlan/nic/que_mgt.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/que_mgt.c new file mode 100755 index 000000000000..ae10d8f186a8 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/nic/que_mgt.c @@ -0,0 +1,4786 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: que_mgt.c $ + * + * 02 20 2012 yuche.tsai + * [ALPS00239286] [Need Patch] [Volunteer Patch] + * Ignore BSS operating mode check while composing beacon frame.. + * + * 11 19 2011 eddie.chen + * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog) + * Add xlog for tx + * + * 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 10 2011 tsaiyuan.hsu + * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered + * add debug counters of ar and bb 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 04 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 Xlog 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. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 while tearing down a station connection. + * + * 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. + * + * 06 27 2011 tsaiyuan.hsu + * [WCXRP00000816] [MT6620 Wi-Fi][Driver] add control to enable rx data dump or not + * add control to enable rx data dump by packet type. + * + * 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) + * Deauth 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. + * + * 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 after WLAN module removed. + * + * 04 07 2011 eddie.chen + * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma + * Add debug. + * + * 04 07 2011 eddie.chen + * [WCXRP00000527] [MT6620 Wi-Fi][FW/Driver] Clean buffered packet when BSS is inactive or disconnected[WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma + * Remove packet when BSS is inactive + * + * 04 07 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 Klocwork 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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) Chnage 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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 +******************************************************************************** +*/ +__KAL_INLINE__ VOID +qmDetermineStaRecIndex( + IN P_ADAPTER_T prAdapter, + IN P_MSDU_INFO_T prMsduInfo + ); + +__KAL_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 + ); + +__KAL_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 Managment 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 + + //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; + +#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; + +// ASSERT(prQM->u4TimeToAdjust && prQM->u4TimeToUpdateQueLen); + + 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; + + 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; + + + 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_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[%ld]\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")); + qmDeactivateStaRec(prAdapter, prStaRec->ucIndex); // To flush TX/RX queues and del RX BA agreements + } + + //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; iaprRxReorderParamRefTbl)[i] = NULL; + } +#endif + + DBGLOG(QM, INFO, ("QM: +STA[%ld]\n", 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; + + 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(prNeedToFreeQue, (P_QUE_ENTRY_T)prMsduInfo); + } + else { + 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; + + 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; iarRxBaTable[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(%ld)\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; + P_QUE_T prTxQue; + QUE_T 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){ + 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; + + DBGLOG(QM, LOUD , ("***** ucStaRecIndex = %d *****\n", + prCurrentMsduInfo->ucStaRecIndex)); + + + prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prCurrentMsduInfo->ucNetworkType]); + + if(IS_NET_ACTIVE(prAdapter, prCurrentMsduInfo->ucNetworkType)) { + + 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); + + ASSERT(prStaRec); + 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){ + 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; + break; + case 6: + case 7: + prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC3]; + ucTC = TC3_INDEX; + eAci = WMM_AC_VO_INDEX; + 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; + } + } + else{ + prTxQue = &prStaRec->arTxQueue[TX_QUEUE_INDEX_AC1]; + ucTC = TC1_INDEX; + } + } + while(fgCheckACMAgain); + + //LOG_FUNC ("QoS %u UP %u TC %u",prStaRec->fgIsQoS,prCurrentMsduInfo->ucUserPriority, ucTC); + + break; /*default */ + } /* switch (prCurrentMsduInfo->ucStaRecIndex) */ + + if(prCurrentMsduInfo->eSrc == TX_PACKET_FORWARDING) { + if(prTxQue->u4NumElem > 32) { + DBGLOG(QM, INFO, ("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, INFO, ("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 + QUEUE_INSERT_TAIL(prTxQue, (P_QUE_ENTRY_T)prCurrentMsduInfo); + + +#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; + } + + + //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; + + 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){ + 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 + if(prBssInfo->fgIsNetAbsent && (ucTC!=TC4_INDEX)) { + 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 = %lu\n", + ucTC, *pu4HeadStaRecIndex)); + + //4 <2> Dequeue packets from the head STA + + prCurrQueue = &prStaRec->arTxQueue[ucTC]; + prDequeuedPkt = NULL; + fgChangeHeadSta = FALSE; + + 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){ + break; + } + else{ + + QUEUE_REMOVE_HEAD(prCurrQueue, prDequeuedPkt, P_MSDU_INFO_T); +#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: " MACSTR "\n", + MAC2STR(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)) { + ASSERT(pucFreeQuota); + ASSERT(*pucFreeQuota>0); + if(*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 = %lu, u4HeadStaRecForwardCount = %lu\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){ + 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 = %lu\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; + } + else{ + + 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: " MACSTR "\n", + MAC2STR(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)) { + prDequeuedPkt->ucPsForwardingType = PS_FORWARDING_MORE_DATA_ENABLED; + } + + QUEUE_INSERT_TAIL(prQue,(P_QUE_ENTRY_T)prDequeuedPkt); + 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 = %lu Left Resource = %lu\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; + } + else{ + 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); + 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: " MACSTR "\n", + MAC2STR(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); + 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 + ) +{ + + INT_32 i; + P_MSDU_INFO_T prReturnedPacketListHead; + QUE_T rReturnedQue; + + DBGLOG(QM, LOUD, ("Enter qmDequeueTxPackets\n")); + + QUEUE_INITIALIZE(&rReturnedQue); + + prReturnedPacketListHead = NULL; + + /* 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[%u]\n", i)); + + qmDequeueTxPacketsFromPerStaQueues( + prAdapter, + &rReturnedQue, + (UINT_8)i, + prTcqStatus->aucFreeBufferCount[i], + prTcqStatus->aucMaxNumOfBuffer[i] + ); + + /* The aggregate number of dequeued packets */ + DBGLOG(QM, LOUD, ("DQA)[%u](%lu)\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 initialize */ + 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]){ + ai4ExtraQuota[i] = prTcqStatus->aucFreeBufferCount[i]; + fgResourceRedistributed = FALSE; + } + + i4TotalExtraQuota += ai4ExtraQuota[i]; + 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){ + if ((-ai4ExtraQuota[i]) > i4TotalExtraQuota){ + ai4ExtraQuota[i] = (-i4TotalExtraQuota); + fgResourceRedistributed = FALSE; + } + + i4TotalExtraQuota += ai4ExtraQuota[i]; + prTcqAdjust->acVariation[i] = (INT_8)(-ai4ExtraQuota[i]); + } + } + + /* In case some TC is waiting for TX Done, continue to adjust TC quotas upon TX Done */ + 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 */ + 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); + } + else{ + 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 + /* Check whether it is time to adjust the TC resource assignment */ + if (--prQM->u4TimeToAdjustTcResource == 0){ + /* The last assignment has not been completely applied */ + if (prQM->fgTcResourcePostAnnealing){ + /* Upon the next qmUpdateAverageTxQueLen function call, do this check again */ + prQM->u4TimeToAdjustTcResource = 1; + } + + /* The last assignment has been applied */ + else{ + prQM->u4TimeToAdjustTcResource = QM_INIT_TIME_TO_ADJUST_TC_RSC; + qmReassignTcResource(prAdapter); + } + } + + /* Debug */ +#if QM_PRINT_TC_RESOURCE_CTRL + for (i=0; i= 100){ + DBGLOG(QM, LOUD, ("QM: QueLen [%ld %ld %ld %ld %ld %ld]\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 + */ + + //4 <1> Determine the demands + /* Determine the amount of extra resource to fulfill all of the demands */ + for (i=0; iau4MinReservedTcResource[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; + } + + i4TotalResourceDemand += ai4PerTcResourceDemand[i]; + } + + //4 <2> Case 1: Demand <= Total Resource + if (i4TotalResourceDemand <= 0){ + //4 <2.1> Satisfy every TC + for (i = 0; i < TC_NUM; i++){ + /* Skip TC4 (not adjustable) */ + if (i == TC4_INDEX) { + continue; + } + + prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; + } + + //4 <2.2> Share the residual resource evenly + u4ShareCount= (TC_NUM - 1); /* excluding TC4 */ + u4ResidualResource = (UINT_32)(-i4TotalResourceDemand); + u4Share = (u4ResidualResource/u4ShareCount); + + for (i=0; iau4CurrentTcResource[i] += u4Share; + + /* Every TC is fully satisfied */ + ai4PerTcResourceDemand[i] = 0; + + /* The left resource will be allocated to TC3 */ + u4ResidualResource -= u4Share; + } + + //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 = QM_INITIAL_RESIDUAL_TC_RESOURCE; + + //4 <3.1> Allocated resouce amount = minimum of (guaranteed, total demand) + for (i=0; iau4CurrentTcResource[i] + ai4PerTcResourceDemand[i] < prQM->au4GuaranteedTcResource[i]){ + prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; + u4ResidualResource += (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); + ai4PerTcResourceDemand[i] = 0; + } + + /* The demand can not be fulfilled with the guaranteed resource amount */ + else{ + ai4PerTcResourceDemand[i] -= (prQM->au4GuaranteedTcResource[i] - prQM->au4CurrentTcResource[i]); + prQM->au4CurrentTcResource[i] = prQM->au4GuaranteedTcResource[i]; + 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; iau4CurrentTcResource[i] += u4Share; + u4ResidualResource -= u4Share; + ai4PerTcResourceDemand[i] -= u4Share; + } + else{ + prQM->au4CurrentTcResource[i] += ai4PerTcResourceDemand[i]; + u4ResidualResource -= ai4PerTcResourceDemand[i]; + ai4PerTcResourceDemand[i] = 0; + } + } + } + } + + /* By priority, allocate the left resource that is not divisible by u4Share */ + if (u4ResidualResource == 0){ + break; + } + + 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); + } + + prQM->fgTcResourcePostAnnealing = TRUE; + +#if QM_PRINT_TC_RESOURCE_CTRL + /* Debug print */ + DBGLOG(QM, LOUD, ("QM: TC Rsc %ld %ld %ld %ld %ld %ld\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 Managment 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; + + //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", + HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr), + prHifRxHdr->ucStaRecIdx, + prCurrSwRfb->ucWlanIdx, + HIF_RX_HDR_GET_SN(prHifRxHdr), /* The new SN of the frame */ + HIF_RX_HDR_GET_TID(prHifRxHdr), + prCurrSwRfb->ucPacketType, + HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr))); + + DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prCurrSwRfb->pvHeader, prCurrSwRfb->u2PacketLen); + } +#endif + + 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( prAdapter->rRxCtrl.rFreeSwRfbList.u4NumElem + > (CFG_RX_MAX_PKT_NUM - CFG_NUM_OF_QM_RX_PKT_NUM) ) { + + if(IS_BSS_ACTIVE(prBssInfo)) { + 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)) { + 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 */ + } + else { + DBGLOG(QM, TRACE, ("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; + } + + } + else { + /* Dont not occupy other SW RFB */ + DBGLOG(QM, TRACE, ("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; + } + + } + + /* 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)){ +#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); + + + /* 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; + + DEBUGFUNC("qmProcessPktWithReordering"); + + ASSERT(prSwRfb); + ASSERT(prReturnedQue); + ASSERT(prSwRfb->prHifRxHdr); + + 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](%ld){%ld,%ld}\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 + + + qmPopOutDueToFallWithin(prReorderQueParm, prReturnedQue); + } + /* 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); + + } + /* 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 + + /* 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; + + ASSERT(prSwRfb); + ASSERT(prReturnedQue); + ASSERT(prSwRfb->prHifRxHdr); + + 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](%ld){%d,%d}\n", prSwRfb->ucTid, u4SSN, prReorderQueParm->u2WinStart, prReorderQueParm->u2WinEnd)); + qmPopOutDueToFallAhead(prReorderQueParm, prReturnedQue); + } + else{ + DBGLOG(QM, TRACE, ("QM:(BAR)(%d)(%ld){%ld,%ld}\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 ++; + +} + + +VOID +qmPopOutDueToFallWithin( + 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, 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); + +} + +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{ + return (u4SnLess < u4SnGreater); + } +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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, INFO, ("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; iarRxBaTable[i].fgIsValid){ + if((prQM->arRxBaTable[i].ucStaRecIdx == ucStaRecIdx) && + (prQM->arRxBaTable[i].ucTid == ucTid)){ + return &prQM->arRxBaTable[i]; + } + } + } + return NULL; +} + +BOOL +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; + } + else{ + /* Find the free-to-use BA entry */ + for(i=0; iarRxBaTable[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; + + 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; + + 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 */ + else{ + 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: + { + + UINT_8 ucQosInfo; + UINT_8 ucQosInfoAC; + UINT_8 ucBmpAC; + 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; + 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)){ + return; + } + + /* Determine whether QoS is enabled with the association */ + else{ + 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; + 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); + } + + DBGLOG(QM, TRACE, ("MQM: Assoc_Rsp Parsing (QoS Enabled=%d)\n", prStaRec->fgIsQoS)); + 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; + + 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))){ + + 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 */ + } + else{ + P_AC_QUE_PARMS_T prAcQueParams; + P_IE_WMM_PARAM_T prIeWmmParam; + ENUM_WMM_ACI_T eAci; + PUINT_8 pucWmmParamSetCount; + //int i; + + 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){ + if(*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, ("MQM: eAci = %d, ACM = %d, Aifsn = %d, CWmin = %d, CWmax = %d, TxopLimit = %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 +*/ +/*----------------------------------------------------------------------------*/ +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; + + /* Goal: Determine whether the peer supports WMM/QoS and UAPSDU */ + 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 Param IE with a wrong length */ + } + else{ + 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 */ + } + else{ + 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; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + 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; + + 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); + + 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 intial 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); + +} + + +#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 + + +/*----------------------------------------------------------------------------*/ +/*! +* @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; + + 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 + }; + + P_BSS_INFO_T prBssInfo; + P_STA_RECORD_T prStaRec; + ENUM_WMM_ACI_T eAci; + + 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; } + +#if 0 // 20120220 frog: update beacon content & change OP mode is a separate event for P2P network. + 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); + + 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 intial 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); + +} + + + + +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_STRUC_INSPECTING_ASSERT(QM_MGMT_QUUEUD_THRESHOLD <= (NIC_TX_BUFF_COUNT_TC4)); + DATA_STRUC_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)) { + return FRAME_ACTION_TX_PKT; + } + + } + + DBGLOG(QM, INFO, ("Drop packets Action (Inactive %u).\n",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) { + ASSERT(prMsduInfo!=NULL); + 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) { + break; + } + } + 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){ + if(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; + } + else { + 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; + } + else { + 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; + } + else { + 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, TRACE, ("NAF=%d,%d,%d\n", + prEventBssStatus->ucNetTypeIdx, prBssInfo->fgIsNetAbsent, prBssInfo->ucBssFreeQuota)); + + if(!prBssInfo->fgIsNetAbsent) { + QM_DBG_CNT_INC(&(prAdapter->rQM),QM_DBG_CNT_27); + } + else { + 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); + + //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); + + 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 + ) +{ + + UINT_8 ucFreeQuotaForNonDelivery; + UINT_8 ucFreeQuotaForDelivery; + + ASSERT(prStaRec); + DBGLOG(QM, LOUD, ("qmUpdateFreeQuota orig ucFreeQuota=%d Mode %u New %u\n", + prStaRec->ucFreeQuota, ucUpdateMode, ucFreeQuota )); + + if(!prStaRec->fgIsInPS)return; + + 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(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 { + /* !prStaRec->fgIsUapsdSupported */ + ucFreeQuotaForNonDelivery = ucFreeQuota; + ucFreeQuotaForDelivery = 0; + } + } /* ucFreeQuota > 0 */ + + prStaRec->ucFreeQuotaForDelivery = ucFreeQuotaForDelivery; + prStaRec->ucFreeQuotaForNonDelivery = ucFreeQuotaForNonDelivery; + + 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; iarRxBaTable[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; +} + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_bow.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_bow.c new file mode 100755 index 000000000000..5fc877f9abe4 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_bow.c @@ -0,0 +1,1459 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_bow.c $ + * + * 02 16 2012 chinghwa.yu + * [ALPS00235223] [20110216 Chinghwa] + + +[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] + + +orig Feature_Name : Others + + +[Customer Priority]: 1.High + +[Customer Issue Type(Classification)]: CNN + +[Original owner]: mtk54109 Xi Huang (#67198) + + +[Submitter Information]:VEND_YONGXU CEN + +TEL: 028-66189617?823 + +EMAIL: cenyongxu@mgsei.com + +[Finder Information]: Yongxu Cen + +TEL: 028-66767232?¤ÀÉó?823 + +EMAIL: cenyongxu@mgsei.com + + +The device reboot automatically and then the "KE" pops up after you turn on the "Airplane mode".(once) + + +Happened time¡G10:47 + + +SW Version:ALPS.ICS.FDD.p25 + + +Reference phone¡GThis issue doesn't exist in Nexus S. + + +Contact¡Gmtk@mgsei.com 028-66767232?¤ÀÉó?823. + + + * [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 + * [ALPS00118114] [Rose][ICS][Free Test][Bluetooth]The "KE" pops up after you turn on the airplane mode.(5/5) + * + * Rejects PAL char device operation after BOW is unregistered. + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 + * Add new feature - multiple physical link support. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 03 06 2011 chinghwa.yu + * [WCXRP00000065] Update BoW design and settings + * Sync BOW Driver to latest person development branch version.. + * + * 03 03 2011 jeffrey.chang + * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue + * support concurrent network + * + * 03 03 2011 jeffrey.chang + * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue + * replace alloc_netdev to alloc_netdev_mq for BoW + * + * 03 03 2011 jeffrey.chang + * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue + * modify net device relative functions to support multiple H/W queues + * + * 02 15 2011 chinghwa.yu + * [WCXRP00000065] Update BoW design and settings + * Update net register and BOW for concurrent features. + * + * 02 10 2011 chinghwa.yu + * [WCXRP00000065] Update BoW design and settings + * Fix kernel API change issue. + * Before ALPS 2.2 (2.2 included), kfifo_alloc() is + * struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock); + * After ALPS 2.3, kfifo_alloc() is changed to + * int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask); + * + * 02 09 2011 cp.wu + * [WCXRP00000430] [MT6620 Wi-Fi][Firmware][Driver] Create V1.2 branch for MT6620E1 and MT6620E3 + * create V1.2 driver branch based on label MT6620_WIFI_DRIVER_V1_2_110209_1031 + * with BOW and P2P enabled as default + * + * 02 08 2011 chinghwa.yu + * [WCXRP00000065] Update BoW design and settings + * Replace kfifo_get and kfifo_put with kfifo_out and kfifo_in. + * Update BOW get MAC status, remove returning event for AIS network type. + * + * 01 12 2011 cp.wu + * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP + * implementation of separate BT_OVER_WIFI data path. + * + * 01 12 2011 cp.wu + * [WCXRP00000356] [MT6620 Wi-Fi][Driver] fill mac header length for security frames 'cause hardware header translation needs such information + * fill mac header length information for 802.1x frames. + * + * 11 11 2010 chinghwa.yu + * [WCXRP00000065] Update BoW design and settings + * Fix BoW timer assert issue. + * + * 09 14 2010 chinghwa.yu + * NULL + * Add bowRunEventAAAComplete. + * + * 09 14 2010 cp.wu + * NULL + * correct typo: POLLOUT instead of POLL_OUT + * + * 09 13 2010 cp.wu + * NULL + * add waitq for poll() and read(). + * + * 08 24 2010 chinghwa.yu + * NULL + * Update BOW for the 1st time. + * + * 07 08 2010 cp.wu + * + * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository. + * + * 06 06 2010 kevin.huang + * [WPD00003832][MT6620 5931] Create driver base + * [MT6620 5931] Create driver base + * + * 05 05 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * change variable names for multiple physical link to match with coding convention + * + * 05 05 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * multiple BoW interfaces need to compare with peer address + * + * 04 28 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * change prefix for data structure used to communicate with 802.11 PAL + * to avoid ambiguous naming with firmware interface + * + * 04 28 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * fix kalIndicateBOWEvent. + * + * 04 27 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * add multiple physical link support + * + * 04 13 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * add framework for BT-over-Wi-Fi support. + * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability + * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically + * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose +** +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include "precomp.h" +#include +#include "bss.h" + +#if CFG_ENABLE_BT_OVER_WIFI + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +/* @FIXME if there is command/event with payload length > 28 */ +#define MAX_BUFFER_SIZE (64) + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +#if CFG_BOW_TEST + UINT_32 g_u4PrevSysTime = 0; + UINT_32 g_u4CurrentSysTime = 0; + UINT_32 g_arBowRevPalPacketTime[11]; +#endif + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +// forward declarations +static ssize_t +mt6620_ampc_read( + IN struct file *filp, + IN char __user *buf, + IN size_t size, + IN OUT loff_t *ppos); + +static ssize_t +mt6620_ampc_write( + IN struct file *filp, + OUT const char __user *buf, + IN size_t size, + IN OUT loff_t *ppos); + +static long +mt6620_ampc_ioctl( + IN struct file *filp, + IN unsigned int cmd, + IN OUT unsigned long arg); + +static unsigned int +mt6620_ampc_poll( + IN struct file *filp, + IN poll_table *wait); + +static int +mt6620_ampc_open( + IN struct inode *inodep, + IN struct file *filp); + +static int +mt6620_ampc_release( + IN struct inode *inodep, + IN struct file *filp); + + +// character file operations +static const struct file_operations mt6620_ampc_fops = { + .owner = THIS_MODULE, + .read = mt6620_ampc_read, + .write = mt6620_ampc_write, + .unlocked_ioctl = mt6620_ampc_ioctl, + .poll = mt6620_ampc_poll, + .open = mt6620_ampc_open, + .release = mt6620_ampc_release, +}; + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Register for character device to communicate with 802.11 PAL +* +* \param[in] prGlueInfo Pointer to glue info +* +* \return TRUE +* FALSE +*/ +/*----------------------------------------------------------------------------*/ +BOOLEAN +glRegisterAmpc ( + IN P_GLUE_INFO_T prGlueInfo + ) +{ + ASSERT(prGlueInfo); + + if(prGlueInfo->rBowInfo.fgIsRegistered == TRUE) { + return FALSE; + } + else { +#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; + } + else { + 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->u4Flag & 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; + + 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->u4Flag & 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->u4Flag & 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->u4Flag & 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->u4Flag & 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: %d/%d\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)); + + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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]; + + 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); + return NETDEV_TX_OK; + } + + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + DBGLOG(BOW, TRACE, ("GLUE_FLAG_HALT skip tx\n")); + dev_kfree_skb(prSkb); + 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) { + 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, ether_setup, CFG_MAX_TXQ_NUM); + + if (!prGlueInfo->rBowInfo.prDevHandler) { + return FALSE; + } + else { + /* 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 + memcpy(prGlueInfo->rBowInfo.prDevHandler->dev_addr, rMacAddr, ETH_ALEN); + memcpy(prGlueInfo->rBowInfo.prDevHandler->perm_addr, prGlueInfo->rBowInfo.prDevHandler->dev_addr, ETH_ALEN); + + /* 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->func->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/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_init.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_init.c new file mode 100755 index 000000000000..77642622fa66 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_init.c @@ -0,0 +1,2810 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/gl_init.c#5 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_init.c $ + * + * 02 23 2012 yuche.tsai + * [ALPS00240485] [Wifi P2P]Run Sigma tool of A69. Always run fail on 6.1.2 and 6.1.3. sniffer check no framename,proberesp,P2P_IE,0 + * 1. Recompose probe response frame in driver, in order to sync the IEs between supplicant & driver. + * 2. Under GO mode, indicate probe request to supplicant due to WSC IE sync issue. + * Davinci Label: 20120223_ALPS_WIFI_FW_V2_1. + * + * 02 14 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Replace Beacon/Probe Response IE by driver generating instead of from supplicant. + * + * 02 06 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Small bug fix for CNM memory usage, scan SSID search issue, P2P network deactivate issue. + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 01 17 2012 wh.su + * [WCXRP00001173] [MT6620 Wi-Fi][Driver] Adding the ICS Tethering WPA2-PSK supporting + * Adding the related code which support beacon can reflect the security setting open or WPA2-PSK, WPA-PSK not yet + * Adn support the indicate the assoc request ie at New STA CMD, needed kernel patch. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 01 11 2012 terry.wu + * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork + * Notify tx_thread to do p2p init for cfg80211 rfkill workaround. + * + * 12 22 2011 george.huang + * [WCXRP00000768] [MT6620 Wi-Fi][FW] Modification for code size shrink + * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before TX thread handling + * + * 11 19 2011 yuche.tsai + * NULL + * Add P2P RSSI Link Quality Query Support. (Default Off) + * + * 11 14 2011 yuche.tsai + * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue. + * Large Network Type index assert. + * Fix NULL prDev 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 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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: + * 1) firmware: collect MDRDY counter to decide which is the most sparse channel + * 2) 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. + * Support TX Deauth while tearing down a station connection. + * + * 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 05 2011 yuche.tsai + * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue + * Export one function 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 cp.wu + * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events + * sync. whole-chip resetting mechanism to V2.0 branch. + * + * 04 14 2011 yuche.tsai + * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case. + * Refine P2P connection flow for Sigma Test. + * + * 04 12 2011 cm.chang + * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency + * . + * + * 04 11 2011 yuche.tsai + * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue. + * Fix multiple export symbol issue. + * + * 04 11 2011 george.huang + * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode + * export wlan functions to p2p + * + * 04 11 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Alway keep the latest Bss type when RX Beacon. + * + * 04 10 2011 yuche.tsai + * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO. + * Add device discoverability support. (Phase I) + * + * 04 07 2011 eddie.chen + * [WCXRP00000527] [MT6620 Wi-Fi][FW/Driver] Clean buffered packet when BSS is inactive or disconnected[WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma + * Remove packet when BSS is inactive + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 similiar 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 managment 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 "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include "precomp.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +//#define MAX_IOREQ_NUM 10 + +BOOLEAN fgIsUnderEarlierSuspend = false; + +struct semaphore g_halt_sem; +int g_u4HaltFlag = 0; + + +/******************************************************************************* +* 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 +******************************************************************************** +*/ + +MODULE_AUTHOR(NIC_AUTHOR); +MODULE_DESCRIPTION(NIC_DESC); +MODULE_SUPPORTED_DEVICE(NIC_NAME); + +#if MTK_WCN_HIF_SDIO + MODULE_LICENSE("MTK Propietary"); +#else + MODULE_LICENSE("GPL"); +#endif + +//#ifdef MODULE_LICENSE +// MODULE_LICENSE("GPL"); +//#endif /* MODULE_LICENSE */ + +#define NIC_INF_NAME "wlan%d" /* interface name */ + +#if DBG + UINT_8 aucDebugModule[DBG_MODULE_NUM]; + UINT_32 u4DebugModule = 0; +#endif /* DBG */ + +//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 = 0; /* How many NICs coexist now */ + +//static UINT_32 u4PacketFilter = 0; +//static UINT_8 aucMCAddrList[MAX_NUM_GROUP_ADDR][ETH_ALEN]; + + +#if 0 //CFG_SUPPORT_WAPI + #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + static int UseWapi = 1; + MODULE_PARM (UseWapi, "i"); + #else + static int UseWapi = 0; + module_param(UseWapi, int, S_IRUGO | S_IWUSR); + MODULE_PARM_DESC(UseWapi, "Use Wapi mode"); + #endif +#endif + +/******************************************************************************* +* 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 + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +extern int glRegisterEarlySuspend( + struct early_suspend *prDesc, + early_suspend_callback wlanSuspend, + late_resume_callback wlanResume); + +extern int glUnregisterEarlySuspend(struct early_suspend *prDesc); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) +/*----------------------------------------------------------------------------*/ +/*! +* \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) +{ + skb->priority = _cfg80211_classify8021d(skb); + + return au16Wlan1dToQueueIdx[skb->priority]; +} +#endif + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 + 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)); + } + + // 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]; + } + } + } + } + else { + prGlueInfo->fgNvramAvailable = FALSE; + } + + return; +} + + +#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->u4Flag |= 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); + + 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 + ) +{ + //4 Mark HALT, notify main thread to finish current job + prGlueInfo->u4Flag |= 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--; + } + } + + return; +} /* 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 WLAN_STATUS_SUCCESS The IOCTL command is executed successfully. +* \retval OTHER 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, WARN, ("%s Invalid input data\n", __FUNCTION__)); + return -EINVAL; + } + + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + DBGLOG(INIT, WARN, ("%s No glue info\n", __FUNCTION__)); + return -EFAULT; + } + + if (prGlueInfo->u4ReadyFlag == 0) { + return -EINVAL; + } + + //printk ("ioctl %x\n", i4Cmd); + + if (i4Cmd == SIOCGIWPRIV) { + /* 0x8B0D, get private ioctl table */ + ret = wext_get_priv(prDev, prIFReq); + } + else 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 { + DBGLOG(INIT, WARN, ("Unexpected ioctl command: 0x%04x\n", i4Cmd)); + /* return 0 for safe? */ + } + + 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 work_struct workq; +static struct net_device *gPrDev; + +static void +wlanSetMulticastList (struct net_device *prDev) +{ + gPrDev = prDev; + schedule_work(&workq); +} + +/* 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; + + down(&g_halt_sem); + if (g_u4HaltFlag) { + up(&g_halt_sem); + 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)); + up(&g_halt_sem); + 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) || +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) { +#else + (prDev->mc_count > MAX_NUM_GROUP_ADDR)) { +#endif + + u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST; + } + else { + u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST; + } + } + + up(&g_halt_sem); + + if (kalIoctl(prGlueInfo, + wlanoidSetCurrentPacketFilter, + &u4PacketFilter, + sizeof(u4PacketFilter), + FALSE, + FALSE, + TRUE, + FALSE, + &u4SetInfoLen) != WLAN_STATUS_SUCCESS) { + return; + } + + + if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) { + /* Prepare multicast address list */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + struct netdev_hw_addr *ha; +#else + struct dev_mc_list *prMcList; +#endif + PUINT_8 prMCAddrList = NULL; + UINT_32 i = 0; + + down(&g_halt_sem); + if (g_u4HaltFlag) { + up(&g_halt_sem); + return; + } + + prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) + netdev_for_each_mc_addr(ha, prDev) { + if(i < MAX_NUM_GROUP_ADDR) { + memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN); + i++; + } + } +#else + for (i = 0, prMcList = prDev->mc_list; + (prMcList) && (i < prDev->mc_count) && (i < MAX_NUM_GROUP_ADDR); + i++, prMcList = prMcList->next) { + memcpy((prMCAddrList + i * ETH_ALEN), prMcList->dmi_addr, ETH_ALEN); + } +#endif + + up(&g_halt_sem); + + kalIoctl(prGlueInfo, + wlanoidSetMulticastList, + prMCAddrList, + (i * ETH_ALEN), + FALSE, + FALSE, + TRUE, + FALSE, + &u4SetInfoLen); + + kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN); + } + + return; +} /* end of wlanSetMulticastList() */ + + +/* 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) { + + ASSERT(prGlueInfo); + + if (!prGlueInfo) { + DBGLOG(INIT, WARN, ("abnormal dev or skb: prGlueInfo(0x%p)\n", + prGlueInfo)); + return; + } + +#if CFG_ENABLE_WIFI_DIRECT + if(prGlueInfo->prAdapter->fgIsP2PRegistered) { + P_P2P_FUNCTION_LINKER prFuncLkr = &(prGlueInfo->prAdapter->rP2pFuncLkr); + prFuncLkr->prP2pSetMulticastListWorkQueue(prGlueInfo); + } +#endif + + return; +} /* end of p2pSetMulticastListWorkQueueWrapper() */ + + + +/*----------------------------------------------------------------------------*/ +/*! +* \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_BOW_TEST + UINT_32 i; +#endif + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prSkb); + ASSERT(prDev); + ASSERT(prGlueInfo); + + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + DBGLOG(INIT, INFO, ("GLUE_FLAG_HALT skip tx\n")); + dev_kfree_skb(prSkb); + 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, ("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) { + + #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 + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + u2QueueIdx = skb_get_queue_mapping(prSkb); + ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM); +#endif + + 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 LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { + netif_stop_subqueue(prDev, u2QueueIdx); + } +#else + if (prGlueInfo->i4TxPendingFrameNum >= CFG_TX_STOP_NETIF_QUEUE_THRESHOLD) { + netif_stop_queue(prDev); + } +#endif + } 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++; + + //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 (!prDev) { + return -ENXIO; + } + + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12) + INIT_WORK(&workq, wlanSetMulticastListWorkQueue); +#else + INIT_WORK(&workq, wlanSetMulticastListWorkQueue, NULL); +#endif + + + 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 + ) +{ + return; +} /* 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); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + netif_tx_start_all_queues(prDev); +#else + netif_start_queue(prDev); +#endif + + 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 + ) +{ + ASSERT(prDev); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + netif_tx_stop_all_queues(prDev); +#else + netif_stop_queue(prDev); +#endif + + return 0; /* success */ +} /* end of wlanStop() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 net_device *prDev + ) +{ + INT_32 i4DevIdx = -1; + + ASSERT(prDev); + + + /* GeorgeKuo: register_netdev() helps translate wlan%d to wlan0; it + * calls rtnl_lock() and rtnl_unlock() to do protection for + * register_netdevice(). Avoid using register_netdevice() directly. + */ + //rtnl_lock(); + + do { + if (!prDev) { + break; + } + + if ((i4DevIdx = wlanGetDevIdx(prDev)) < 0) { + DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device number exceeds.\n")); + break; + } + + if (register_netdev(prDev) < 0) { + DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device context is not registered.\n")); + wlanClearDevIdx(prDev); + i4DevIdx = -1; + } + } + while(FALSE); + + //rtnl_unlock(); + + return i4DevIdx; /* success */ +} /* end of wlanNetRegister() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Unregister the device from the kernel +* +* \param[in] prDev Pointer to struct net_device. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +static VOID +wlanNetUnregister( + struct net_device *prDev + ) +{ + /* Waiting for executing tasklet completion. + * Note: before tasklet completion, all resources should be kept. + */ + + /* GeorgeKuo: unregister_netdev() uses rtnl_lock() to protect + * unregister_netdevice(). Avoid using unregister_netdevice() directly. + */ + + //rtnl_lock(); + + if (!prDev) { + //rtnl_unlock(); + DBGLOG(INIT, ERROR, ("wlanNetUnregister: The device context is NULL\n")); + //ASSERT(prDev); + return; + } + + wlanClearDevIdx(prDev); + + DBGLOG(INIT, INFO, ("unregistering netdev (0x%p)\n", prDev)); + unregister_netdev(prDev); + DBGLOG(INIT, INFO, ("unregistration completed\n")); + + return; +} /* end of wlanNetUnregister() */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) +static const struct net_device_ops wlan_netdev_ops = { + .ndo_open = wlanOpen, + .ndo_stop = wlanStop, + .ndo_set_multicast_list = wlanSetMulticastList, + .ndo_get_stats = wlanGetStats, + .ndo_do_ioctl = wlanDoIOCTL, + .ndo_start_xmit = wlanHardStartXmit, + .ndo_init = wlanInit, + .ndo_uninit = wlanUninit, + .ndo_select_queue = wlanSelectQueue, +}; +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* \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 net_device object. +* \retval NULL Fail to create net_device object +*/ +/*----------------------------------------------------------------------------*/ +static struct net_device * +wlanNetCreate( + PVOID pvData + ) +{ + struct net_device *prDev = NULL; + P_GLUE_INFO_T prGlueInfo = NULL; + P_ADAPTER_T prAdapter = NULL; + UINT_32 i; + + //4 <1> Create netdev +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + prDev = alloc_netdev_mq(sizeof(GLUE_INFO_T), NIC_INF_NAME, ether_setup, CFG_MAX_TXQ_NUM); +#else + prDev = alloc_netdev(sizeof(GLUE_INFO_T), NIC_INF_NAME, ether_setup); +#endif + + DBGLOG(INIT, INFO, ("net_device prDev(0x%p) allocated\n", prDev)); + + if (!prDev) { + DBGLOG(INIT, ERROR, ("Allocating memory to net_device context failed\n")); + return NULL; + } + + //4 <2> Create Glue structure + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + + if (!prGlueInfo) { + DBGLOG(INIT, ERROR, ("Allocating memory to glue layer failed\n")); + goto netcreate_err; + } + + //4 <3> Initial Glue structure + prGlueInfo->prDevHandler = prDev; + prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; + prGlueInfo->ePowerState = ParamDeviceStateD0; + prGlueInfo->fgIsMacAddrOverride = FALSE; + + 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]); + } + + /* initialize semaphore for ioctl */ + sema_init(&prGlueInfo->ioctl_sem, 1); + + /* initialize semaphore for ioctl */ + sema_init(&g_halt_sem, 1); + g_u4HaltFlag = 0; + + + //4 <4> Create Adapter structure + prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo); + + if (!prAdapter) { + DBGLOG(INIT, ERROR, ("Allocating memory to adapter failed\n")); + goto netcreate_err; + } + + prGlueInfo->prAdapter = prAdapter; + + //4 <6> Register Callback function +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31) + prDev->netdev_ops = &wlan_netdev_ops; +#else + prDev->open = wlanOpen; + prDev->stop = wlanStop; + /*prDev->change_mtu = wlanChangeMTU;*/ + prDev->get_stats = wlanGetStats; + prDev->set_multicast_list = wlanSetMulticastList; + prDev->hard_start_xmit = wlanHardStartXmit; + + /* GeorgeKuo: wait to be removed? */ + prDev->do_ioctl = wlanDoIOCTL; + prDev->init = wlanInit; + prDev->uninit = wlanUninit; +#endif + + //4 <7> Use wireless extension to replace IOCTL + prDev->wireless_handlers = &wext_handler_def; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD +#if 0 //CFG_SUPPORT_WAPI + if (!UseWapi) { + prDev->features = NETIF_F_IP_CSUM; + } + else { + wlanSetWapiMode(prAdapter, UseWapi); + } +#else + + //prDev->features = NETIF_F_IP_CSUM; + prDev->features = NETIF_F_HW_CSUM; +#endif +#else +#if 0//CFG_SUPPORT_WAPI + if (UseWapi) { + wlanSetWapiMode(prAdapter, UseWapi); + } +#endif +#endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */ + + netif_carrier_off(prDev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + netif_tx_stop_all_queues(prDev); +#else + netif_stop_queue(prDev); +#endif + + goto netcreate_done; + +netcreate_err: + if (NULL != prAdapter) { + wlanAdapterDestroy(prAdapter); + prAdapter = NULL; + } + + if (NULL != prDev) { + /* Free net_device and private data, which are allocated by + * alloc_netdev(). + */ + free_netdev(prDev); + prDev = NULL; + } + +netcreate_done: + + return prDev; +} /* end of wlanNetCreate() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Destroying the struct net_device object and the private data. +* +* \param[in] prDev Pointer to struct net_device. +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +static VOID +wlanNetDestroy( + struct net_device *prDev + ) +{ + P_GLUE_INFO_T prGlueInfo = NULL; + + ASSERT(prDev); + + if (!prDev) { + DBGLOG(INIT, ERROR, ("wlanNetDestroy: The device context is NULL\n")); + return; + } + + /* prGlueInfo is allocated with net_device */ + prGlueInfo = netdev_priv(prDev); + ASSERT(prGlueInfo); + + /* destroy kal OS timer */ + kalCancelTimer(prGlueInfo); + + glClearHifInfo(prGlueInfo); + + wlanAdapterDestroy(prGlueInfo->prAdapter); + prGlueInfo->prAdapter = NULL; + + /* Free net_device and private data, which are allocated by alloc_netdev(). + */ + free_netdev(prDev); + + return; +} /* end of wlanNetDestroy() */ + +#ifndef CONFIG_X86 +UINT_8 g_aucBufIpAddr[32] = {0}; + +static void wlanEarlySuspend(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; + + DBGLOG(INIT, INFO, ("*********wlanEarlySuspend************\n")); + + // <1> Sanity check and acquire the net_device + ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); + prDev = arWlanDevInfo[u4WlanDevNum-1].prDev; + ASSERT(prDev); + + // <2> acquire the prGlueInfo + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + ASSERT(prGlueInfo); + +fgIsUnderEarlierSuspend = true; + + // <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(INIT, INFO, ("ip is not avaliable.\n")); + return; + } + + // <4> copy the IPv4 address + kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); + DBGLOG(INIT, 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 + // <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(INIT, INFO, ("ipv6 is not avaliable.\n")); + return; + } + // <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] + )); + + // 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 + + // <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 + u4NumIPv6; + 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)); + u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS); +#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)); + u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); + } +#endif + ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/)); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetNetworkAddress, + (PVOID)prParamNetAddrList, + u4Len, + FALSE, + FALSE, + TRUE, + FALSE, + &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus)); + } + } +} + +static void wlanLateResume(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 + + DBGLOG(INIT, INFO, ("*********wlanLateResume************\n")); + + // <1> Sanity check and acquire the net_device + ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); + prDev = arWlanDevInfo[u4WlanDevNum-1].prDev; + ASSERT(prDev); + + // <2> acquire the prGlueInfo + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + ASSERT(prGlueInfo); + +fgIsUnderEarlierSuspend = false; + + // <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(INIT, INFO, ("ip is not avaliable.\n")); + return; + } + + // <4> copy the IPv4 address + kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip)); + DBGLOG(INIT, INFO, ("ip is %d.%d.%d.%d\n", + ip[0],ip[1],ip[2],ip[3])); + +#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(INIT, INFO, ("ipv6 is not avaliable.\n")); + return; + } + // <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 + { + 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, + wlanoidSetNetworkAddress, + (PVOID)prParamNetAddrList, + u4Len, + FALSE, + FALSE, + TRUE, + FALSE, + &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus)); + } + } +} + +static struct early_suspend mt6620_early_suspend_desc = { + .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN, +}; + +#if defined(CONFIG_HAS_EARLYSUSPEND) +static void wlan_early_suspend(struct early_suspend *h) +{ + DBGLOG(INIT, INFO, ("*********wlan_early_suspend************\n")); + wlanEarlySuspend(); +} + +static void wlan_late_resume(struct early_suspend *h) +{ + DBGLOG(INIT, INFO, ("*********wlan_late_resume************\n")); + wlanLateResume(); +} +#endif //defined(CONFIG_HAS_EARLYSUSPEND) +#endif //! CONFIG_X86 + +/*----------------------------------------------------------------------------*/ +/*! +* \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 net_device *prDev = NULL; + 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; + BOOL bRet = FALSE; + + + do { +#if DBG + int i; + /* Initialize DEBUG CLASS of each module */ + for (i = 0; i < DBG_MODULE_NUM; i++) { + aucDebugModule[i] = DBG_CLASS_ERROR | \ + DBG_CLASS_WARN | \ + DBG_CLASS_STATE | \ + DBG_CLASS_TRACE | \ + DBG_CLASS_EVENT; + //aucDebugModule[i] = 0; + } +#if 0 + aucDebugModule[DBG_INIT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_ARB_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_JOIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + //aucDebugModule[DBG_RX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_TX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_NIC_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_HAL_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_KEVIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_TEMP; + aucDebugModule[DBG_SCAN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_REQ_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + //aucDebugModule[DBG_MGT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; + aucDebugModule[DBG_RSN_IDX] |= DBG_CLASS_TRACE; + aucDebugModule[DBG_ROAMING_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO; +#endif +#endif /* DBG */ + + //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); + + /* Cannot get IO address from interface */ + if (FALSE == bRet) { + DBGLOG(INIT, ERROR, (KERN_ALERT "wlanProbe: glBusInit() fail\n")); + i4Status = -EIO; + break; + } + + //4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev) + if ((prDev = wlanNetCreate(pvData)) == NULL) { + DBGLOG(INIT, ERROR, ("wlanProbe: No memory for dev and its private\n")); + i4Status = -ENOMEM; + break; + } + + //4 <2.5> Set the ioaddr to HIF Info + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + gPrDev = prDev; + glSetHifInfo(prGlueInfo, (UINT_32) pvData); + + + /* main thread is created in this function */ + init_waitqueue_head(&prGlueInfo->waitq); + // + + QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue); + QUEUE_INITIALIZE(&prGlueInfo->rTxQueue); + + + + //prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread"); + + //4 <4> Setup IRQ + prWlandevInfo = &arWlanDevInfo[i4DevIdx]; + + //i4Status = glBusSetIrq(prDev, NULL, netdev_priv(prDev)); + + if (i4Status != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, ERROR, ("wlanProbe: Set IRQ error\n")); + 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 + + + //4 <5> Start Device + // +#if CFG_ENABLE_FW_DOWNLOAD + /* 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); + + //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; + goto bailout; + } else { + if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, u4FwSize) != WLAN_STATUS_SUCCESS) { + i4Status = -EIO; + } + } + + kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer); + +bailout: + //kfree(prRegInfo); + + if (i4Status < 0) { + 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; + break; + } +#endif + prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread"); + + /* set MAC address */ + { + WLAN_STATUS rStatus = WLAN_STATUS_FAILURE; + struct sockaddr MacAddr; + UINT_32 u4SetInfoLen = 0; + + 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%lx\n", rStatus)); + prGlueInfo->u4ReadyFlag = 0; + } else { + memcpy(prGlueInfo->prDevHandler->dev_addr, &MacAddr.sa_data, ETH_ALEN); + memcpy(prGlueInfo->prDevHandler->perm_addr, prGlueInfo->prDevHandler->dev_addr, ETH_ALEN); + + /* card is ready */ + prGlueInfo->u4ReadyFlag = 1; + } + } + + +#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%lx\n", rStatus)); + } + } +#endif + + //4 <3> Register the card + if ((i4DevIdx = wlanNetRegister(prDev)) < 0){ + i4Status = -ENXIO; + DBGLOG(INIT, ERROR, ("wlanProbe: Cannot register the net_device context to the kernel\n")); + break; + } + + //4 <6> Initialize /proc filesystem +#ifdef WLAN_INCLUDE_PROC + if ( (i4Status = procInitProcfs(prDev, NIC_DEVICE_ID_LOW)) < 0) { + DBGLOG(INIT, ERROR, ("wlanProbe: init procfs failed\n")); + 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 + /*wlan is launched*/ + prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE; + /*if p2p module is inserted, notify tx_thread to init p2p network*/ + if(rSubModHandler[P2P_MODULE].subModInit) { + //4 Mark SUB_MOB_INIT, notify main thread to finish current job + prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_INIT; + } +#endif + } + while (FALSE); + + 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 + ) +{ + struct net_device *prDev = NULL; + P_WLANDEV_INFO_T prWlandevInfo = NULL; + P_GLUE_INFO_T prGlueInfo = NULL; + P_ADAPTER_T prAdapter = NULL; + + DBGLOG(INIT, INFO, ("Remove wlan!\n")); + + + //4 <0> Sanity check + ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES); + if (0 == u4WlanDevNum) { + DBGLOG(INIT, INFO, ("0 == u4WlanDevNum\n")); + return; + } + + prDev = arWlanDevInfo[u4WlanDevNum-1].prDev; + prWlandevInfo = &arWlanDevInfo[u4WlanDevNum-1]; + + ASSERT(prDev); + if (NULL == prDev) { + DBGLOG(INIT, INFO, ("NULL == prDev\n")); + return; + } + + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + ASSERT(prGlueInfo); + if (NULL == prGlueInfo) { + DBGLOG(INIT, INFO, ("NULL == prGlueInfo\n")); + free_netdev(prDev); + return; + } + + +#if CFG_ENABLE_WIFI_DIRECT + prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE; + if(prGlueInfo->prAdapter->fgIsP2PRegistered) { + wlanSubModExit(prGlueInfo); + } + +#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 + glBusFreeIrq(prDev, netdev_priv(prDev)); + + kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T)); + + flush_scheduled_work(); + + down(&g_halt_sem); + g_u4HaltFlag = 1; + + //4 <2> Mark HALT, notify main thread to stop, and clean up queued requests + prGlueInfo->u4Flag |= GLUE_FLAG_HALT; + /* wake up main thread */ + wake_up_interruptible(&prGlueInfo->waitq); + /* wait main thread stops */ + wait_for_completion_interruptible(&prGlueInfo->rHaltComp); + + DBGLOG(INIT, INFO, ("mtk_sdiod stopped\n")); + + //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(prDev, NIC_DEVICE_ID_LOW); +#endif /* WLAN_INCLUDE_PROC */ + + //4 <4> wlanAdapterStop + prAdapter = prGlueInfo->prAdapter; + + wlanAdapterStop(prAdapter); + DBGLOG(INIT, INFO, ("Number of Stalled Packets = %ld\n", prGlueInfo->i4TxPendingFrameNum)); + + //4 <5> Release the Bus + glBusRelease(prDev); + + up(&g_halt_sem); + flush_scheduled_work(); + + //4 <6> Unregister the card + wlanNetUnregister(prDev); + + //4 <7> Destroy the device + wlanNetDestroy(prDev); + prDev = NULL; + + return; +} /* end of wlanRemove() */ +extern void wlanRegisterNotifier(void); +extern void wlanUnregisterNotifier(void); + +/*----------------------------------------------------------------------------*/ +/*! +* \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 __init initWlan(void) +{ + int ret = 0; + + DBGLOG(INIT, INFO, ("initWlan\n")); + + /* memory pre-allocation */ + kalInitIOBuffer(); + + //return ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO); + ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO); + + if (ret == -EIO) { + kalUninitIOBuffer(); + return ret; + } + + glRegisterEarlySuspend(&mt6620_early_suspend_desc, wlan_early_suspend, wlan_late_resume); + wlanRegisterNotifier(); + +#if (CFG_CHIP_RESET_SUPPORT) + glResetInit(); +#endif + + 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 __exit exitWlan(void) +{ + //printk("remove %p\n", wlanRemove); + glUnregisterEarlySuspend(&mt6620_early_suspend_desc); + wlanUnregisterNotifier(); + +#if CFG_CHIP_RESET_SUPPORT + glResetUninit(); +#endif + + glUnregisterBus(wlanRemove); + + /* free pre-allocated memory */ + kalUninitIOBuffer(); + + DBGLOG(INIT, INFO, ("exitWlan\n")); + + return; +} /* end of exitWlan() */ + +module_init(initWlan); +module_exit(exitWlan); + +/* export necessary symbol for p2p driver using */ +#if CFG_ENABLE_WIFI_DIRECT +EXPORT_SYMBOL(wlanSubModRegisterInitExit); +EXPORT_SYMBOL(wlanSubModExit); +EXPORT_SYMBOL(wlanSubModInit); + +EXPORT_SYMBOL(nicPmIndicateBssCreated); +EXPORT_SYMBOL(rlmProcessAssocRsp); +EXPORT_SYMBOL(kalSetEvent); +EXPORT_SYMBOL(rlmBssInitForAPandIbss); +EXPORT_SYMBOL(kalEnqueueCommand); +EXPORT_SYMBOL(nicIncreaseTxSeqNum); +EXPORT_SYMBOL(nicCmdEventQueryAddress); +EXPORT_SYMBOL(bssCreateStaRecFromBssDesc); +EXPORT_SYMBOL(rlmBssAborted); +EXPORT_SYMBOL(cnmStaRecResetStatus); +EXPORT_SYMBOL(mqmProcessAssocRsp); +EXPORT_SYMBOL(nicTxReturnMsduInfo); +EXPORT_SYMBOL(nicTxEnqueueMsdu); +EXPORT_SYMBOL(wlanProcessSecurityFrame); +EXPORT_SYMBOL(nicChannelNum2Freq); +EXPORT_SYMBOL(nicUpdateBss); +EXPORT_SYMBOL(wlanSendSetQueryCmd); +EXPORT_SYMBOL(cnmStaRecAlloc); +EXPORT_SYMBOL(cnmTimerInitTimer); +EXPORT_SYMBOL(rateGetRateSetFromIEs); +EXPORT_SYMBOL(nicOidCmdTimeoutCommon); +EXPORT_SYMBOL(cnmStaRecChangeState); +EXPORT_SYMBOL(rateGetDataRatesFromRateSet); +EXPORT_SYMBOL(cnmMgtPktAlloc); +EXPORT_SYMBOL(cnmMgtPktFree); +EXPORT_SYMBOL(wextSrchDesiredWPAIE); +EXPORT_SYMBOL(nicRxReturnRFB); +EXPORT_SYMBOL(cnmTimerStartTimer); +EXPORT_SYMBOL(cmdBufAllocateCmdInfo); +EXPORT_SYMBOL(cnmGetStaRecByAddress); +EXPORT_SYMBOL(nicMediaStateChange); +EXPORT_SYMBOL(bssUpdateBeaconContent); +EXPORT_SYMBOL(kalIoctl); +EXPORT_SYMBOL(nicActivateNetwork); +EXPORT_SYMBOL(nicDeactivateNetwork); +EXPORT_SYMBOL(kalRandomNumber); +EXPORT_SYMBOL(nicCmdEventSetCommon); +EXPORT_SYMBOL(cnmTimerStopTimer); +EXPORT_SYMBOL(nicIncreaseCmdSeqNum); +EXPORT_SYMBOL(authSendDeauthFrame); +EXPORT_SYMBOL(cnmMemAlloc); +EXPORT_SYMBOL(nicPmIndicateBssAbort); +EXPORT_SYMBOL(nicCmdEventSetIpAddress); +EXPORT_SYMBOL(mboxSendMsg); +EXPORT_SYMBOL(scanSearchBssDescByBssid); +EXPORT_SYMBOL(bssRemoveStaRecFromClientList); +EXPORT_SYMBOL(assocProcessRxDisassocFrame); +EXPORT_SYMBOL(authProcessRxDeauthFrame); +EXPORT_SYMBOL(cnmStaRecFree); +EXPORT_SYMBOL(rNonHTPhyAttributes); +EXPORT_SYMBOL(rNonHTApModeAttributes); +EXPORT_SYMBOL(cnmMemFree); +EXPORT_SYMBOL(wlanExportGlueInfo); +EXPORT_SYMBOL(bssInitForAP); +EXPORT_SYMBOL(nicPmIndicateBssConnected); +EXPORT_SYMBOL(rlmRspGenerateHtOpIE); +EXPORT_SYMBOL(bssGenerateExtSuppRate_IE); +EXPORT_SYMBOL(rlmRspGenerateErpIE); +EXPORT_SYMBOL(rlmRspGenerateHtCapIE); +EXPORT_SYMBOL(cnmGetStaRecByIndex); +EXPORT_SYMBOL(rsnGenerateWpaNoneIE); +EXPORT_SYMBOL(rlmRspGenerateExtCapIE); +EXPORT_SYMBOL(rsnGenerateRSNIE); +EXPORT_SYMBOL(rsnParseRsnIE); +#if CFG_SUPPORT_WPS +EXPORT_SYMBOL(wextSrchDesiredWPSIE); +#endif +EXPORT_SYMBOL(mboxDummy); +EXPORT_SYMBOL(saaFsmRunEventStart); +EXPORT_SYMBOL(saaFsmRunEventAbort); +EXPORT_SYMBOL(cnmP2PIsPermitted); +EXPORT_SYMBOL(cnmBss40mBwPermitted); +EXPORT_SYMBOL(mqmGenerateWmmParamIE); +EXPORT_SYMBOL(cnmPreferredChannel); +EXPORT_SYMBOL(bssAddStaRecToClientList); +EXPORT_SYMBOL(nicQmUpdateWmmParms); +EXPORT_SYMBOL(qmFreeAllByNetType); +EXPORT_SYMBOL(wlanQueryInformation); +EXPORT_SYMBOL(nicConfigPowerSaveProfile); +EXPORT_SYMBOL(scanSearchExistingBssDesc); +EXPORT_SYMBOL(scanAllocateBssDesc); +EXPORT_SYMBOL(wlanProcessCommandQueue); +EXPORT_SYMBOL(wlanAcquirePowerControl); +EXPORT_SYMBOL(wlanReleasePowerControl); +EXPORT_SYMBOL(wlanReleasePendingCMDbyNetwork); +#if DBG +EXPORT_SYMBOL(aucDebugModule); +EXPORT_SYMBOL(fgIsBusAccessFailed); +EXPORT_SYMBOL(allocatedMemSize); +EXPORT_SYMBOL(dumpMemory8); +EXPORT_SYMBOL(dumpMemory32); +#endif +EXPORT_SYMBOL(rlmDomainIsLegalChannel); +EXPORT_SYMBOL(scnQuerySparseChannel); +EXPORT_SYMBOL(rlmDomainGetChnlList); +EXPORT_SYMBOL(p2pSetMulticastListWorkQueueWrapper); +EXPORT_SYMBOL(nicUpdateRSSI); +EXPORT_SYMBOL(nicCmdEventQueryLinkQuality); +EXPORT_SYMBOL(kalGetMediaStateIndicated); +EXPORT_SYMBOL(nicFreq2ChannelNum); +EXPORT_SYMBOL(assocSendDisAssocFrame); +EXPORT_SYMBOL(nicUpdateBeaconIETemplate); +EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem); +EXPORT_SYMBOL(kalClearMgmtFramesByNetType); +EXPORT_SYMBOL(kalClearSecurityFramesByNetType); +EXPORT_SYMBOL(nicFreePendingTxMsduInfoByNetwork); +EXPORT_SYMBOL(bssComposeBeaconProbeRespFrameHeaderAndFF); +EXPORT_SYMBOL(bssBuildBeaconProbeRespFrameCommonIEs); +#endif + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_kal.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_kal.c new file mode 100755 index 000000000000..5ed39f2afad7 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_kal.c @@ -0,0 +1,3660 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/gl_kal.c#2 $ +*/ + +/*! \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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_kal.c $ + * + * 03 26 2012 cp.wu + * [ALPS00255324] wifi ???¤£¤W¡Awps?¤£¤Wªº??¤´¦s¦b + * invoke put_cred() after get_current_cred() calls to release a reference + * + * 03 26 2012 yuche.tsai + * [ALPS00255551] [WiFi direct][Google Issue]GC can't send picture to GO sometimes,GO and GC can't ping each other + * Avoid ran out of driver resource when starting GO. + * + * 02 20 2012 cp.wu + * [ALPS00239244] [MT6620 Wi-Fi][Driver] Improve error handling while firmware image doesn't exist + * no need to free buffer if firmware image doesn't exis. + * + * 02 06 2012 wh.su + * [ALPS00109161] [Need Patch] [Volunteer Patch] [Wi-Fi] Support the set tx power driver cmd + * Adding the AP mode channel query filter. + * + * 02 06 2012 yuche.tsai + * [ALPS00118350] [ALPS.ICS][WiFi Direct] Dirver update for wifi direct connection + * Small bug fix for CNM memory usage, scan SSID search issue, P2P network deactivate issue. + * + * 01 13 2012 yuche.tsai + * NULL + * WiFi Hot Spot Tethering for ICS ALPHA testing version. + * + * 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 19 2011 yuche.tsai + * NULL + * Add P2P RSSI Link Quality Query Support. (Default 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 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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. + * + * 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 + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 similiar 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 availble 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 managment macro + * + * 05 17 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * 1) add timeout handler mechanism for pending command packets + * 2) add p2p add/removal key + * + * 05 14 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * Disable network interface after disassociation + * + * 05 10 2010 cp.wu + * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support + * fill network type field while doing frame identification. + * + * 05 07 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * prevent supplicant accessing driver during resume + * + * 04 27 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame + * + * 04 27 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * 1) fix firmware download bug + * 2) remove query statistics for acelerating firmware download + * + * 04 27 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * follow Linux's firmware framework, and remove unused kal API + * + * 04 22 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * + * 1) modify rx path code for supporting Wi-Fi direct + * 2) modify config.h since Linux dont need to consider retaining packet + * + * 04 21 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * add for private ioctl support + * + * 04 15 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * change firmware name + * + * 04 14 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * flush pending TX packets while unloading driver + * + * 04 14 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * Set driver own before handling cmd queue + * + * 04 14 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used + * 2) fix ioctl + * + * 04 14 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * information buffer for query oid/ioctl is now buffered in prCmdInfo + * * * * * * * instead of glue-layer variable to improve multiple oid/ioctl capability + * + * 04 13 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * add framework for BT-over-Wi-Fi support. + * * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability + * * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically + * * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose + * + * 04 09 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * fix spinlock usage + * + * 04 09 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * add spinlock for i4TxPendingFrameNum access + * + * 04 09 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * 1) add spinlock + * * 2) add KAPI for handling association info + * + * 04 09 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * fix spinlock usage + * + * 04 09 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * adding firmware download KAPI + * + * 04 07 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * Set MAC address from firmware + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1. free cmdinfo after command is emiited. + * 2. for BoW frames, user priority is extracted from sk_buff directly. + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * finish non-glue layer access to glue variables + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * accessing to firmware load/start address, and access to OID handling information + * * * are now handled in glue layer + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * rWlanInfo should be placed at adapter rather than glue due to most operations + * * * * * * * are done in adapter layer. + * + * 04 07 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer + * + * 04 06 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * (1)deliver the kalOidComplete status to upper layer + * (2) fix spin lock + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * add KAL API: kalFlushPendingTxPackets(), and take use of the API + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer. + * + * 04 06 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * add timeout check in the kalOidComplete + * + * 04 06 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * improve none-glue code portability + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer + * + * 04 06 2010 cp.wu + * [WPD00001943]Create WiFi test driver framework on WinXP + * 1) for some OID, never do timeout expiration + * * * 2) add 2 kal API for later integration + * + * 04 06 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * raising the priority of processing interrupt + * + * 04 01 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in + * + * 03 30 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * emulate NDIS Pending OID facility + * + * 03 28 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * adding secondary command queue for improving non-glue code portability + * + * 03 26 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * [WPD00003826] Initial import for Linux port + * adding firmware download kal api + * + * 03 25 2010 cp.wu + * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support + * add Bluetooth-over-Wifi frame header check + * + * 03 24 2010 jeffrey.chang + * [WPD00003826]Initial import for Linux port + * initial import for Linux port +** \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090 +** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel. +** \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090 +** Add Linux SDIO (with mmc core) support. +** Add Linux 2.6.21, 2.6.25, 2.6.26. +** Fix compile warning in Linux. +** \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090 +** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support +** \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088 +** fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding +** \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461 +** Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL +** \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088 +** remove non-used code for code review, add assert check +** \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461 +** \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461 +** Rename KAL function +** \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461 +** \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084 +** rename wlanoid +** \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084 +** remove un-used KAL function +** \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461 +** Move Query Media Status to GLUE +** \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461 +** change awake queue threshold and remove code which mark #if 0 +** \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461 +** Add iwpriv support for AdHocMode setting +** \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084 +** add KAL function to setting pattern search function enable/ disable +** \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461 +** Add comment +** \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461 +** Add update MAC Address for Linux +** \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084 +** update function for initial value access +** \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088 +** use kal update associate request at linux +** \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385 +** 1. add Query Registry Mac address function. +** \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084 +** modify KAL set network address/ checksum offload part +** \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461 +** Add debug option - Packet Order for Linux +** \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084 +** modify the argument of kalQueryPacketInfo() +** \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425 +** 1. Revise csum offload +** \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425 +** 1. Fix bugs +** +** \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461 +** Fix Windows RX multiple packet retain problem +** \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088 +** CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit +** \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425 +** 1. Modify for CSUM offloading with Tx Fragment +** \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461 +** Add Tx Fragmentation Support +** \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088 +** add the WPS code, indicate the mgmt frame to upper layer +** \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461 +** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning +** \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425 +** 1. Update wlanQueryInformation +** \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425 +** 1. Refine multicast list code +** 2. Refine TCP/IP csum offload code +** +** Revision 1.5 2007/07/17 13:01:18 MTK01088 +** add associate req and rsp function +** +** Revision 1.4 2007/07/13 05:19:19 MTK01084 +** provide timer set functions +** +** Revision 1.3 2007/06/27 02:18:51 MTK01461 +** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API +** +** Revision 1.2 2007/06/25 06:16:24 MTK01461 +** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API +** +*/ + +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "gl_os.h" +#include "gl_wext.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 +******************************************************************************** +*/ +#if DBG +int allocatedMemSize = 0; +#endif + +extern struct semaphore g_halt_sem; +extern int g_u4HaltFlag; + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static PVOID pvIoBuffer = NULL; +static UINT_32 pvIoBufferSize = 0; +static UINT_32 pvIoBufferUsage = 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; + +extern ENUM_WMTHWVER_TYPE_T +mtk_wcn_wmt_hwver_get( + VOID + ); +#elif defined(MT5931) && CFG_MULTI_ECOVER_SUPPORT +typedef enum _ENUM_HWVER_TYPE_T{ + HWVER_MT5931_E1 = 0x1, + HWVER_MT5931_E2 = 0x2, + HWVER_MT5931_E3 = 0x3, + HWVER_MT5931_MAX, + HWVER_INVALID = 0xff +} ENUM_HWVER_TYPE_T, *P_ENUM_HWVER_TYPE_T; +#endif + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#if CFG_ENABLE_FW_DOWNLOAD + +static struct file *filp = NULL; +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 + ) +{ + /* 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) */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + orgfsuid = current->fsuid; + orgfsgid = current->fsgid; + current->fsuid = current->fsgid = 0; +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + struct cred *cred = (struct cred *) get_current_cred(); + orgfsuid = cred->fsuid; + orgfsgid = cred->fsgid; + cred->fsuid = cred->fsgid = 0; +#else + struct cred *cred = get_task_cred(current); + orgfsuid = cred->fsuid; + orgfsgid = cred->fsgid; + cred->fsuid = cred->fsgid = 0; +#endif + + ASSERT(prGlueInfo); + + + orgfs = get_fs(); + set_fs(get_ds()); + + + /* open the fw file */ +#if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT + switch(mtk_wcn_wmt_hwver_get()) { + case WMTHWVER_MT6620_E1: + case WMTHWVER_MT6620_E2: + case WMTHWVER_MT6620_E3: + case WMTHWVER_MT6620_E4: + case WMTHWVER_MT6620_E5: + filp = filp_open("/etc/firmware/"CFG_FW_FILENAME, O_RDONLY, 0); + break; + + case WMTHWVER_MT6620_E6: + default: + filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_E6", O_RDONLY, 0); + break; + } +#elif defined(MT5931) && CFG_MULTI_ECOVER_SUPPORT + switch (wlanGetEcoVersion(prGlueInfo->prAdapter)) { + case HWVER_MT5931_E1: + case HWVER_MT5931_E2: + filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_E2", O_RDONLY, 0); + break; + case HWVER_MT5931_E3: + default: + filp = filp_open("/etc/firmware/"CFG_FW_FILENAME, O_RDONLY, 0); + break; + } +#else + filp = filp_open("/etc/firmware/"CFG_FW_FILENAME, O_RDONLY, 0); +#endif + if (IS_ERR(filp)) { + DBGLOG(INIT, INFO, ("Open FW image: %s failed\n", CFG_FW_FILENAME)); + goto error_open; + } + DBGLOG(INIT, INFO, ("Open FW image: %s done\n", CFG_FW_FILENAME)); + return WLAN_STATUS_SUCCESS; + +error_open: + /* restore */ + set_fs(orgfs); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + current->fsuid = orgfsuid; + current->fsgid = orgfsgid; +#else + cred->fsuid = orgfsuid; + cred->fsgid = orgfsgid; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + put_cred(cred); + #endif +#endif + 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); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + current->fsuid = orgfsuid; + current->fsgid = orgfsgid; +#else + { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + struct cred *cred = (struct cred *) get_current_cred(); +#else + struct cred *cred = get_task_cred(current); +#endif + cred->fsuid = orgfsuid; + cred->fsgid = orgfsgid; + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) + put_cred(cred); + #endif + } +#endif + 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; + + /* 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); + } + + 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); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12) + *pu4Size = filp->f_path.dentry->d_inode->i_size; +#else + *pu4Size = filp->f_dentry->d_inode->i_size; +#endif + + 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 + ) +{ + DEBUGFUNC("kalFirmwareImageMapping"); + + ASSERT(prGlueInfo); + ASSERT(ppvMapFileBuf); + ASSERT(pu4FileLength); + + do { + /* <1> Open firmware */ + if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) { + break; + } else { + UINT_32 u4FwSize = 0; + PVOID prFwBuffer = NULL; + /* <2> Query firmare size */ + kalFirmwareSize(prGlueInfo, &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); + 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->func->dev); + + if (i4Ret) { + printk (KERN_INFO DRV_NAME"fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret); + break; + } else { + *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 PUINT_32 pu4Flags + ) +{ + UINT_32 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; + } + + return; +} /* 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) { + +#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 */ + + } + + return; +} /* 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); + } + + return; +} + + +#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 LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) + if (skb->ip_summed == CHECKSUM_HW) +#else + if (skb->ip_summed == CHECKSUM_PARTIAL) +#endif + { + +#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 != __constant_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; + + return; +} /* 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 { + + } +#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); +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 = %#lx, prSkb->cb = %#lx\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 = (unsigned char *)pucPacketStart; + skb->tail = (unsigned char *) ((UINT_32) (pucPacketStart + u4PacketLen)); + skb->len = (unsigned int)u4PacketLen; + +#if CFG_TCP_IP_CHKSUM_OFFLOAD + kalUpdateRxCSUMOffloadParam(skb, aerCSUM); +#endif + + return rStatus; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 = 0x%p, prSkb->cb = 0x%lx\n", pu4Head, u4HeadValue)); + } while (0); +#endif + + if (GLUE_GET_PKT_IS_P2P(prSkb)) { + /* P2P */ +#if CFG_ENABLE_WIFI_DIRECT + if(prGlueInfo->prAdapter->fgIsP2PRegistered) { + prNetDev = prGlueInfo->prAdapter->rP2pFuncLkr.prKalP2pGetDevHdlr(prGlueInfo); + } +#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++; + + } + + 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, EVENT, ("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 LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + if(!in_interrupt()){ + netif_rx_ni(prSkb); /* only in non-interrupt context */ + } + else { + netif_rx(prSkb); + } +#else + netif_rx(prSkb); +#endif + + wlanReturnPacket(prGlueInfo->prAdapter, NULL); + } + + 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) +* +*/ +/*----------------------------------------------------------------------------*/ +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; + + kalMemZero(arBssid, MAC_ADDR_LEN); + + ASSERT(prGlueInfo); + + + switch (eStatus) { + 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 */ + PARAM_SSID_T ssid; + + 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(INIT, INFO, ("[wifi] %s netif_carrier_on [ssid:%s " MACSTR "]\n", + prGlueInfo->prDevHandler->name, + ssid.aucSsid, + MAC2STR(arBssid))); + } while(0); + break; + + case WLAN_STATUS_MEDIA_DISCONNECT: + /* 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 */ + +#if 1 /* CONSOLE_MESSAGE */ + DBGLOG(INIT, INFO, ("[wifi] %s netif_carrier_off\n", prGlueInfo->prDevHandler->name)); +#endif + + netif_carrier_off(prGlueInfo->prDevHandler); + + prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED; + + break; + + case WLAN_STATUS_SCAN_COMPLETE: + /* indicate scan complete event */ + wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0); + 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) [" MACSTR "] F:%lx\n", + pAuth->Request[0].Length, + MAC2STR(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)) { + 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[" MACSTR "] preAuth Flag:%lx\n", + MAC2STR(pPmkid->arCandidateList[0].rBSSID), + pPmkid->arCandidateList[0].fgFlags); + } + */ + { + UINT_32 i = 0; + + P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T)&pPmkid->arCandidateList[0]; + + for (i=0; iu4NumCandidates; i++) { + wext_indicate_wext_event(prGlueInfo, + IWEVPMKIDCAND, + (unsigned char *)&pPmkid->arCandidateList[i], + pPmkid->u4NumCandidates); + prPmkidCand += sizeof(PARAM_PMKID_CANDIDATE_T); + } + } + 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; + + 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); + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + u2QueueIdx = skb_get_queue_mapping(prSkb); +#endif + 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); + GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]); + prDev = prSkb->dev; + + ASSERT(prDev); + + if(fgIsValidDevice == TRUE) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26) + if (netif_subqueue_stopped(prDev, prSkb) && + prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) { + netif_wake_subqueue(prDev, u2QueueIdx); + } +#else + if (prGlueInfo->i4TxPendingFrameNum < CFG_TX_STOP_NETIF_QUEUE_THRESHOLD) { + netif_wake_queue(prGlueInfo->prDevHandler); + } +#endif + } + + + dev_kfree_skb((struct sk_buff *) pvPacket); + + DBGLOG(TX, EVENT, ("----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum)); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + + return; +} /* 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 +* +* @retval TRUE Success to extract information +* @retval FALSE Fail to extract correct information +*/ +/*----------------------------------------------------------------------------*/ + +BOOL +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 + ) +{ + + 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(INIT, WARN, ("Invalid Ether packet length: %d\n", 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; + //printk ("ip version %x\n", ucIpVersion); + 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) { /* For Port Control */ + //DBGLOG(REQ, TRACE, ("Tx 1x\n")); + *pfgIs1X = TRUE; + } + else if (u2EtherTypeLen == ETH_P_PRE_1X) { /* For Pre 1x pkt */ + //DBGLOG(REQ, TRACE, ("Tx Pre-1x\n")); + *pfgIs1X = TRUE; + } +#if CFG_SUPPORT_WAPI + else if (u2EtherTypeLen == ETH_WPI_1X) { + *pfgIs1X = TRUE; + } +#endif + 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) { + *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 + ) +{ + + /* remove timeout check timer */ + wlanoidClearTimeoutCheck(prGlueInfo->prAdapter); + + ASSERT(prGlueInfo); + //if (prGlueInfo->u4TimeoutFlag != 1) { + prGlueInfo->rPendStatus = rOidStatus; + complete(&prGlueInfo->rPendComp); + //} + /* 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); + 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 BOOL fgRead, + IN BOOL fgWaitResp, + IN BOOL fgCmd, + IN BOOL fgIsP2pOid, + OUT PUINT_32 pu4QryInfoLen + ) +{ + P_GL_IO_REQ_T prIoReq = NULL; + WLAN_STATUS ret = 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 (down_interruptible(&g_halt_sem)) { + return WLAN_STATUS_FAILURE; + } + + + if (g_u4HaltFlag) { + up(&g_halt_sem); + return WLAN_STATUS_ADAPTER_NOT_READY; + } + + if(down_interruptible(&prGlueInfo->ioctl_sem)) { + up(&g_halt_sem); + 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; + + /* <6> Check if we use the command queue */ + prIoReq->u4Flag = fgCmd; + + /* <7> schedule the OID bit */ + set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag); + + /* <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)) { + 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 + + up(&prGlueInfo->ioctl_sem); + up(&g_halt_sem); + + 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); +} + + + +/*----------------------------------------------------------------------------*/ +/*! +* @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 sub mod init*/ + if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_INIT_BIT, &prGlueInfo->u4Flag)) { + wlanSubModRunInit(prGlueInfo); + complete(&prGlueInfo->rSubModComp); + } + /*run sub mod exit*/ + if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_EXIT_BIT, &prGlueInfo->u4Flag)) { + wlanSubModRunExit(prGlueInfo); + complete(&prGlueInfo->rSubModComp); + } + + /*run p2p multicast list work. */ + if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->u4Flag)) { + p2pSetMulticastListWorkQueueWrapper(prGlueInfo); + } + + +#endif + + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + 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 + * + */ + + ret = wait_event_interruptible(prGlueInfo->waitq, + (prGlueInfo->u4Flag != 0)); + +#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 sub mod init*/ + if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_INIT_BIT, &prGlueInfo->u4Flag)) { + wlanSubModRunInit(prGlueInfo); + complete(&prGlueInfo->rSubModComp); + } + /*run sub mod exit*/ + if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_EXIT_BIT, &prGlueInfo->u4Flag)) { + wlanSubModRunExit(prGlueInfo); + complete(&prGlueInfo->rSubModComp); + } +#endif + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + 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->u4Flag)) { + + 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->u4Flag & GLUE_FLAG_HALT) { + /* Should stop now... skip pending interrupt */ + DBGLOG(INIT, INFO, ("ignore pending interrupt\n")); + } + else { + + wlanIST(prGlueInfo->prAdapter); + } + } + + /* transfer ioctl to OID request */ + #if 0 + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + printk(KERN_INFO DRV_NAME"<2>tx_thread should stop now...\n"); + break; + } + #endif + + do { + if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag)) { + /* get current prIoReq */ + 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) { + 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) { + printk(KERN_INFO DRV_NAME"<3>tx_thread should stop now...\n"); + break; + } + #endif + + if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->u4Flag)) + { + + /* 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, WARN, ("prSkb == NULL in tx\n")); + continue; + } + + if(wlanEnqueueTxPacket(prGlueInfo->prAdapter, + (P_NATIVE_PACKET)prSkb) == WLAN_STATUS_RESOURCES) { + 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) { + 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->u4Flag)) { + wlanTimerTimeoutCheck(prGlueInfo->prAdapter); + } + + #if CFG_DBG_GPIO_PINS + /* TX thread go to sleep */ + if (!prGlueInfo->u4Flag){ + mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH); + } + #endif + } + + #if 0 + if (fgNeedHwAccess == TRUE) { + wlanReleasePowerControl(prGlueInfo->prAdapter); + } + #endif + + /* 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) + UINT_32 i; + BOOLEAN fgIsReadError = FALSE; + + 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; + } + } + + 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; + } + 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); + + if (prCmdInfo) { + if (prCmdInfo->pfCmdTimeoutHandler) { + prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo); + } + else { + kalOidComplete(prGlueInfo, + prCmdInfo->fgSetQuery, + 0, + WLAN_STATUS_NOT_ACCEPTED); + } + + 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; + + GLUE_SPIN_LOCK_DECLARATION(); + + ASSERT(prGlueInfo); + ASSERT(prQueueEntry); + + prCmdQue = &prGlueInfo->rCmdQueue; + + 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); + GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); +} + +UINT_32 +kalGetTxPendingFrameCount( + IN P_GLUE_INFO_T prGlueInfo + ) +{ + ASSERT(prGlueInfo); + + return (UINT_32)(prGlueInfo->i4TxPendingFrameNum); +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is used to retrieve the number of pending commands +* (including MMPDU, 802.1X and command packets) +* +* \param prGlueInfo Pointer of GLUE Data Structure +* +* \retval +*/ +/*----------------------------------------------------------------------------*/ +UINT_32 +kalGetTxPendingCmdCount( + IN P_GLUE_INFO_T prGlueInfo + ) +{ + P_QUE_T prCmdQue; + + ASSERT(prGlueInfo); + prCmdQue = &prGlueInfo->rCmdQueue; + + return prCmdQue->u4NumElem; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Timer Initialization Procedure +* +* \param[in] prGlueInfo Pointer to GLUE Data Structure +* \param[in] prTimerHandler Pointer to timer handling function, whose only +* argument is "prAdapter" +* +* \retval none +* +*/ +/*----------------------------------------------------------------------------*/ + +//static struct timer_list tickfn; + +VOID +kalOsTimerInitialize ( + IN P_GLUE_INFO_T prGlueInfo, + IN PVOID prTimerHandler + ) +{ + + ASSERT(prGlueInfo); + + init_timer(&(prGlueInfo->tickfn)); + prGlueInfo->tickfn.function = prTimerHandler; + prGlueInfo->tickfn.data = (unsigned long) prGlueInfo; +} + +// Todo +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is called to set the time to do the time out check. +* +* \param[in] prGlueInfo Pointer to GLUE Data Structure +* \param[in] rInterval Time out interval from current time. +* +* \retval TRUE Success. +*/ +/*----------------------------------------------------------------------------*/ +BOOLEAN +kalSetTimer( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Interval + ) +{ + ASSERT(prGlueInfo); + del_timer_sync(&(prGlueInfo->tickfn)); + + prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC; + add_timer(&(prGlueInfo->tickfn)); + + return TRUE; /* success */ +} +/*----------------------------------------------------------------------------*/ +/*! +* \brief This routine is called to cancel +* +* \param[in] prGlueInfo Pointer to GLUE Data Structure +* +* \retval TRUE : Timer has been canceled +* FALAE : Timer doens't exist +*/ +/*----------------------------------------------------------------------------*/ +BOOLEAN +kalCancelTimer( + IN P_GLUE_INFO_T prGlueInfo + ) +{ + ASSERT(prGlueInfo); + + clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag); + + 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 + ) +{ + ASSERT(prGlueInfo); + //complete(&prGlueInfo->rScanComp); + 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 (unsigned long arg) +{ + + P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) arg; + + ASSERT(prGlueInfo); + + /* Notify tx thread for timeout event */ + set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag); + wake_up_interruptible(&prGlueInfo->waitq); + + return; +} + + +VOID +kalSetEvent (P_GLUE_INFO_T pr) { + set_bit(GLUE_FLAG_TXREQ_BIT, &pr->u4Flag); + 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); + + return; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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; + pStats->qual.level = 0x100 + cRssi; + pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED; + } + + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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); + } + + pvIoBuffer = kmalloc(u4Size, 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 + ) +{ + if(pvIoBuffer) { + kfree(pvIoBuffer); + + pvIoBuffer = (PVOID) NULL; + pvIoBufferSize = 0; + pvIoBufferUsage = 0; + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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, + ucMaxChannelNum, + pucNumOfChannel, + paucChannelList); +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief +* +* \param[in] prAdapter Pointer of ADAPTER_T +* +* \return none +*/ +/*----------------------------------------------------------------------------*/ +BOOL +kalIsAPmode( + IN P_GLUE_INFO_T prGlueInfo + ) +{ +#if CFG_ENABLE_WIFI_DIRECT + if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) && + prGlueInfo->prAdapter->rP2pFuncLkr.prP2pFuncIsApMode && + prGlueInfo->prAdapter->rP2pFuncLkr.prP2pFuncIsApMode( + prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo)) + return TRUE; +#endif + + return FALSE; +} + + +#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 + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_proc.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_proc.c new file mode 100755 index 000000000000..bef72b031316 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_proc.c @@ -0,0 +1,855 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 "gl_os.h" +#include "gl_kal.h" + +#include "wlan_lib.h" +#include "debug.h" + + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define PROC_MCR_ACCESS "mcr" +#define PROC_DRV_STATUS "status" +#define PROC_RX_STATISTICS "rx_statistics" +#define PROC_TX_STATISTICS "tx_statistics" +#define PROC_DBG_LEVEL "dbg_level" + +#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 +#define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN 30 + + +/******************************************************************************* +* 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 = 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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. +*/ +/*----------------------------------------------------------------------------*/ +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_STRUC_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_STRUC_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'; + + switch (sscanf(acBuf, "0x%lx 0x%lx", + &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData)) { + case 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); + + } + break; + + case 1: + //if (IS_ALIGN_4(rMcrInfo.u4McrOffset)) + { + u4McrOffset = rMcrInfo.u4McrOffset; + } + break; + + default: + break; + } + + return count; + +} /* end of procMCRWrite() */ + +#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 (sscanf(acBuf, "%ld", &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 (sscanf(acBuf, "%ld", &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 + + +#if DBG +static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = { + "DBG_INIT_IDX", + "DBG_HAL_IDX", + "DBG_INTR_IDX", + "DBG_REQ_IDX", + "DBG_TX_IDX", + "DBG_RX_IDX", + "DBG_RFTEST_IDX", + "DBG_EMU_IDX", + "DBG_SW1_IDX", + "DBG_SW2_IDX", + "DBG_SW3_IDX", + "DBG_SW4_IDX", + "DBG_HEM_IDX", + "DBG_AIS_IDX", + "DBG_RLM_IDX", + "DBG_MEM_IDX", + "DBG_CNM_IDX", + "DBG_RSN_IDX", + "DBG_BSS_IDX", + "DBG_SCN_IDX", + "DBG_SAA_IDX", + "DBG_AAA_IDX", + "DBG_P2P_IDX", + "DBG_QM_IDX", + "DBG_SEC_IDX", + "DBG_BOW_IDX" + }; + +extern UINT_8 aucDebugModule[]; + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief The PROC function for displaying current Debug Level. +* +* \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 +procDbgLevelRead ( + char *page, + char **start, + off_t off, + int count, + int *eof, + void *data + ) +{ + char *p = page; + int i; + + + + // Kevin: Apply PROC read method 1. + if (off != 0) { + return 0; // To indicate end of file. + } + + for (i = 0; i < (sizeof(aucDbModuleName)/PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN); i++) { + SPRINTF(p, ("%c %-15s(0x%02x): %02x\n", + ((i == u4DebugModule) ? '*' : ' '), + &aucDbModuleName[i][0], + i, + aucDebugModule[i])); + } + + *eof = 1; + return (int)(p - page); +} + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 int +procDbgLevelWrite ( + struct file *file, + const char *buffer, + unsigned long count, + void *data + ) +{ + char acBuf[PROC_DBG_LEVEL_MAX_USER_INPUT_LEN + 1]; // + 1 for "\0" + UINT_32 u4CopySize; + UINT_32 u4NewDbgModule, u4NewDbgLevel; + + + u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); + copy_from_user(acBuf, buffer, u4CopySize); + acBuf[u4CopySize] = '\0'; + + if (sscanf(acBuf, "0x%lx 0x%lx", &u4NewDbgModule, &u4NewDbgLevel) == 2) { + if (u4NewDbgModule < DBG_MODULE_NUM) { + u4DebugModule = u4NewDbgModule; + u4NewDbgLevel &= DBG_CLASS_MASK; + aucDebugModule[u4DebugModule] = (UINT_8)u4NewDbgLevel; + } + } + + return count; +} +#endif /* DBG */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 +*/ +/*----------------------------------------------------------------------------*/ +INT_32 +procInitProcfs ( + struct net_device *prDev, + char *pucDevName + ) +{ + P_GLUE_INFO_T prGlueInfo; + struct proc_dir_entry *prEntry; + + + ASSERT(prDev); + + if (init_net.proc_net == (struct proc_dir_entry *)NULL) { + DBGLOG(INIT, INFO, ("init proc fs fail: proc_net == NULL\n")); + return -ENOENT; + } + + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + + if (!prGlueInfo) { + DBGLOG(INIT, WARN, ("The OS context is NULL\n")); + return -ENOENT; + } + + + /* + /proc/net/wlan0 + |-- mcr (PROC_MCR_ACCESS) + |-- status (PROC_DRV_STATUS) + |-- rx_statistics (PROC_RX_STATISTICS) + |-- tx_statistics (PROC_TX_STATISTICS) + |-- dbg_level (PROC_DBG_LEVEL) + |-- (end) + */ + + /* + * Directory: Root (/proc/net/wlan0) + */ + + prGlueInfo->pProcRoot = proc_mkdir(pucDevName, init_net.proc_net); + if (prGlueInfo->pProcRoot == NULL) { + return -ENOENT; + } + + /* File Root/mcr (RW) */ + prEntry = create_proc_entry(PROC_MCR_ACCESS, 0, prGlueInfo->pProcRoot); + if (prEntry) { + prEntry->read_proc = procMCRRead; + prEntry->write_proc = procMCRWrite; + prEntry->data = (void *)prDev; + } + +#if 0 + /* File Root/status (RW) */ + prEntry = create_proc_read_entry(PROC_DRV_STATUS, 0, prGlueInfo->pProcRoot, + procDrvStatusRead, prDev); + + /* File Root/rx_statistics (RW) */ + prEntry = create_proc_entry(PROC_RX_STATISTICS, 0, prGlueInfo->pProcRoot); + if (prEntry) { + prEntry->read_proc = procRxStatisticsRead; + prEntry->write_proc = procRxStatisticsWrite; + prEntry->data = (void *)prDev; + } + + /* File Root/tx_statistics (RW) */ + prEntry = create_proc_entry(PROC_TX_STATISTICS, 0, prGlueInfo->pProcRoot); + if (prEntry) { + prEntry->read_proc = procTxStatisticsRead; + prEntry->write_proc = procTxStatisticsWrite; + prEntry->data = (void *)prDev; + } + +#if DBG + /* File Root/dbg_level (RW) */ + prEntry = create_proc_entry(PROC_DBG_LEVEL, 0644, prGlueInfo->pProcRoot); + if (prEntry) { + prEntry->read_proc = procDbgLevelRead; + prEntry->write_proc = procDbgLevelWrite; + } +#endif /* DBG */ +#endif + return 0; + +} /* end of procInitProcfs() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 ( + struct net_device *prDev, + char *pucDevName + ) +{ + P_GLUE_INFO_T prGlueInfo = NULL; + + + ASSERT(prDev); + + if (!prDev) { + return -ENOENT; + } + + if (init_net.proc_net == (struct proc_dir_entry *)NULL) { + DBGLOG(INIT, WARN, ("remove proc fs fail: proc_net == NULL\n")); + return -ENOENT; + } + + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev); + if (!prGlueInfo->pProcRoot) { + DBGLOG(INIT, WARN, ("The procfs root is NULL\n")); + return -ENOENT; + } +#if 0 +#if DBG + remove_proc_entry(PROC_DBG_LEVEL, prGlueInfo->pProcRoot); +#endif /* DBG */ + remove_proc_entry(PROC_TX_STATISTICS, prGlueInfo->pProcRoot); + remove_proc_entry(PROC_RX_STATISTICS, prGlueInfo->pProcRoot); + remove_proc_entry(PROC_DRV_STATUS, prGlueInfo->pProcRoot); +#endif + remove_proc_entry(PROC_MCR_ACCESS, prGlueInfo->pProcRoot); + + /* remove root directory (proc/net/wlan0) */ + remove_proc_entry(pucDevName, init_net.proc_net); + + return 0; + +} /* end of procRemoveProcfs() */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_rst.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_rst.c new file mode 100755 index 000000000000..9a1f1d195463 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_rst.c @@ -0,0 +1,517 @@ +/* +** $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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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 + * sync. whole-chip resetting mechanism to V2.0 branch. + * + * 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 "gl_os.h" +#include "debug.h" +#include "wlan_lib.h" +#include "gl_wext.h" +#include "precomp.h" +#include +#include +#include + +#if CFG_CHIP_RESET_SUPPORT + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define MAX_BIND_PROCESS (4) + +#define MTK_WIFI_FAMILY_NAME "MTK_WIFI" +#define MTK_WIFI_RESET_START_NAME "RESET_START" +#define MTK_WIFI_RESET_END_NAME "RESET_END" +#define MTK_WIFI_RESET_TEST_NAME "GENETLINK_START" + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +enum { + __MTK_WIFI_ATTR_INVALID, + MTK_WIFI_ATTR_MSG, + __MTK_WIFI_ATTR_MAX, +}; +#define MTK_WIFI_ATTR_MAX (__MTK_WIFI_ATTR_MAX - 1) + + +enum { + __MTK_WIFI_COMMAND_INVALID, + MTK_WIFI_COMMAND_BIND, + MTK_WIFI_COMMAND_RESET, + __MTK_WIFI_COMMAND_MAX, +}; +#define MTK_WIFI_COMMAND_MAX (__MTK_WIFI_COMMAND_MAX - 1) + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ +static UINT_32 mtk_wifi_seqnum = 0; +static int num_bind_process = 0; +static pid_t bind_pid[MAX_BIND_PROCESS]; +static BOOLEAN fgIsResetting = FALSE; + +/* attribute policy */ +static struct nla_policy mtk_wifi_genl_policy[MTK_WIFI_ATTR_MAX + 1] = { + [MTK_WIFI_ATTR_MSG] = { .type = NLA_NUL_STRING }, +}; + +/* family definition */ +static struct genl_family mtk_wifi_gnl_family = { + .id = GENL_ID_GENERATE, + .hdrsize = 0, + .name = MTK_WIFI_FAMILY_NAME, + .version = 1, + .maxattr = MTK_WIFI_ATTR_MAX, +}; + +/* forward declaration */ +static int mtk_wifi_bind( + struct sk_buff *skb, + struct genl_info *info + ); + +static int mtk_wifi_reset( + struct sk_buff *skb, + struct genl_info *info + ); + +/* operation definition */ +static struct genl_ops mtk_wifi_gnl_ops_bind = { + .cmd = MTK_WIFI_COMMAND_BIND, + .flags = 0, + .policy = mtk_wifi_genl_policy, + .doit = mtk_wifi_bind, + .dumpit = NULL, +}; + +static struct genl_ops mtk_wifi_gnl_ops_reset = { + .cmd = MTK_WIFI_COMMAND_RESET, + .flags = 0, + .policy = mtk_wifi_genl_policy, + .doit = mtk_wifi_reset, + .dumpit = NULL, +}; + + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ +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 + ); + +static void * +glResetCallback ( + ENUM_WMTDRV_TYPE_T eSrcType, + ENUM_WMTDRV_TYPE_T eDstType, + ENUM_WMTMSG_TYPE_T eMsgType, + void * prMsgBody, + unsigned int u4MsgLength + ); + +static BOOLEAN +glResetSendMessage ( + char *aucMsg, + u8 cmd + ); + + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for + * 1. registering for reset callbacks + * 2. initialize netlink socket + * + * @param none + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +VOID +glResetInit( + VOID + ) +{ + /* 1. register for reset callback */ + mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_WIFI, (PF_WMT_CB)glResetCallback); + + /* 2.1 registration for NETLINK_GENERIC family */ + if(genl_register_family(&mtk_wifi_gnl_family) != 0) { + DBGLOG(INIT, WARN, ("%s(): GE_NELINK family registration fail\n", __func__)); + } + else { + /* 2.2 operation registration */ + if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_bind) != 0) { + DBGLOG(INIT, WARN, ("%s(): BIND operation registration fail\n", __func__)); + } + + if(genl_register_ops(&mtk_wifi_gnl_family, &mtk_wifi_gnl_ops_reset) != 0) { + DBGLOG(INIT, WARN, ("%s(): RESET operation registration fail\n", __func__)); + } + } + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is responsible for + * 1. uninitialize netlink socket + * 2. deregistering for reset callbacks + * + * @param none + * + * @retval none + */ +/*----------------------------------------------------------------------------*/ +VOID +glResetUninit( + VOID + ) +{ + /* 1. release NETLINK_GENERIC family */ + genl_unregister_family(&mtk_wifi_gnl_family); + + /* 2. deregister for reset callback */ + mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_WIFI); + + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @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: + fgIsResetting = TRUE; + glResetSendMessage(MTK_WIFI_RESET_START_NAME, MTK_WIFI_COMMAND_RESET); + break; + + case WMTRSTMSG_RESET_END: + glResetSendMessage(MTK_WIFI_RESET_END_NAME, MTK_WIFI_COMMAND_RESET); + fgIsResetting = FALSE; + break; + + default: + break; + } + } + + break; + + default: + break; + } + + return NULL; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine send out message via netlink socket + * + * @param aucMsg + * u4MsgLength + * + * @retval TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +static BOOLEAN +glResetSendMessage( + char * aucMsg, + u8 cmd + ) +{ + struct sk_buff *skb = NULL; + void *msg_head = NULL; + int rc = -1; + int i; + + if(num_bind_process == 0) { + /* no listening process */ + return FALSE; + } + + for(i = 0 ; i < num_bind_process ; i++) { + skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + + if(skb) { + msg_head = genlmsg_put(skb, 0, mtk_wifi_seqnum++, &mtk_wifi_gnl_family, 0, cmd); + + if(msg_head == NULL) { + nlmsg_free(skb); + return FALSE; + } + + rc = nla_put_string(skb, MTK_WIFI_ATTR_MSG, aucMsg); + if(rc != 0) { + nlmsg_free(skb); + return FALSE; + } + + /* finalize the message */ + genlmsg_end(skb, msg_head); + + /* sending message */ + rc = genlmsg_unicast(&init_net, skb, bind_pid[i]); + if(rc != 0) { + return FALSE; + } + } + else { + return FALSE; + } + } + + return TRUE; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called to identify PID for process binding + * + * @param skb + * info + * + * @retval 0 + * nonzero + */ +/*----------------------------------------------------------------------------*/ +int mtk_wifi_bind( + struct sk_buff *skb, + struct genl_info *info + ) +{ + struct nlattr *na; + char * mydata; + + if (info == NULL) { + goto out; + } + + /*for each attribute there is an index in info->attrs which points to a nlattr structure + *in this structure the data is given + */ + + na = info->attrs[MTK_WIFI_ATTR_MSG]; + if (na) { + mydata = (char *)nla_data(na); + + /* no need to parse mydata */ + } + + /* collect PID */ + if(num_bind_process < MAX_BIND_PROCESS) { + bind_pid[num_bind_process] = info->snd_pid; + num_bind_process++; + } + else { + DBGLOG(INIT, WARN, ("%s(): exceeding binding limit %d\n", __func__, MAX_BIND_PROCESS)); + } + +out: + return 0; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called for reset, shout not happen + * + * @param skb + * info + * + * @retval 0 + * nonzero + */ +/*----------------------------------------------------------------------------*/ +int mtk_wifi_reset( + struct sk_buff *skb, + struct genl_info *info + ) +{ + DBGLOG(INIT, WARN, ("%s(): should not be invoked\n", __func__)); + + return 0; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called for generating reset request to WMT + * + * @param None + * + * @retval None + */ +/*----------------------------------------------------------------------------*/ +VOID +glSendResetRequest( + VOID + ) +{ + // WMT thread would trigger whole chip resetting itself + return; +} + + +/*----------------------------------------------------------------------------*/ +/*! + * @brief This routine is called for checking if MT6620 is resetting + * + * @param None + * + * @retval TRUE + * FALSE + */ +/*----------------------------------------------------------------------------*/ +BOOLEAN +kalIsResetting( + VOID + ) +{ + return fgIsResetting; +} + + +#endif // CFG_CHIP_RESET_SUPPORT diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext.c new file mode 100755 index 000000000000..002c4e0364d0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext.c @@ -0,0 +1,4548 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/gl_wext.c#1 $ +*/ + +/*! \file gl_wext.c + \brief ioctl() (mostly Linux Wireless Extensions) routines for STA driver. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_wext.c $ + * + * 01 20 2012 wh.su + * [ALPS00107209] [Need Patch] [Volunteer Patch][ICS][Wi-Fi] Legacy Wi-Fi with Driver band Cmd support + * Add back the engineer mode ioctl support + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 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 24 2011 terry.wu + * NULL + * Rollback to previous verson due to misbranch check-in + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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.. + * + * 05 17 2011 eddie.chen + * [WCXRP00000603] [MT6620 Wi-Fi][DRV] Fix Klocwork warning + * Initilize 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 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 (throught 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 MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \ + switch (ch) \ + { \ + case 1: khz = 2412000; break; \ + case 2: khz = 2417000; break; \ + case 3: khz = 2422000; break; \ + case 4: khz = 2427000; break; \ + case 5: khz = 2432000; break; \ + case 6: khz = 2437000; break; \ + case 7: khz = 2442000; break; \ + case 8: khz = 2447000; break; \ + case 9: khz = 2452000; break; \ + case 10: khz = 2457000; break; \ + case 11: khz = 2462000; break; \ + case 12: khz = 2467000; break; \ + case 13: khz = 2472000; break; \ + case 14: khz = 2484000; break; \ + case 36: /* UNII */ khz = 5180000; break; \ + case 40: /* UNII */ khz = 5200000; break; \ + case 44: /* UNII */ khz = 5220000; break; \ + case 48: /* UNII */ khz = 5240000; break; \ + case 52: /* UNII */ khz = 5260000; break; \ + case 56: /* UNII */ khz = 5280000; break; \ + case 60: /* UNII */ khz = 5300000; break; \ + case 64: /* UNII */ khz = 5320000; break; \ + case 149: /* UNII */ khz = 5745000; break; \ + case 153: /* UNII */ khz = 5765000; break; \ + case 157: /* UNII */ khz = 5785000; break; \ + case 161: /* UNII */ khz = 5805000; break; \ + case 165: /* UNII */ khz = 5825000; break; \ + case 100: /* HiperLAN2 */ khz = 5500000; break; \ + case 104: /* HiperLAN2 */ khz = 5520000; break; \ + case 108: /* HiperLAN2 */ khz = 5540000; break; \ + case 112: /* HiperLAN2 */ khz = 5560000; break; \ + case 116: /* HiperLAN2 */ khz = 5580000; break; \ + case 120: /* HiperLAN2 */ khz = 5600000; break; \ + case 124: /* HiperLAN2 */ khz = 5620000; break; \ + case 128: /* HiperLAN2 */ khz = 5640000; break; \ + case 132: /* HiperLAN2 */ khz = 5660000; break; \ + case 136: /* HiperLAN2 */ khz = 5680000; break; \ + case 140: /* HiperLAN2 */ khz = 5700000; break; \ + case 34: /* Japan MMAC */ khz = 5170000; break; \ + case 38: /* Japan MMAC */ khz = 5190000; break; \ + case 42: /* Japan MMAC */ khz = 5210000; break; \ + case 46: /* Japan MMAC */ khz = 5230000; break; \ + case 184: /* Japan */ khz = 4920000; break; \ + case 188: /* Japan */ khz = 4940000; break; \ + case 192: /* Japan */ khz = 4960000; break; \ + case 196: /* Japan */ khz = 4980000; break; \ + case 208: /* Japan, means J08 */ khz = 5040000; break; \ + case 212: /* Japan, means J12 */ khz = 5060000; break; \ + case 216: /* Japan, means J16 */ khz = 5080000; break; \ + default: khz = 2412000; break; \ + } \ + } + + +#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, ""}, + + /* 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_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" } +}; + +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, +}; + +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; + } + else { + /* 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_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; + } + else { + /* 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; + + 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); + + /* strcpy(pucName, "IEEE 802.11bg"); */ + + // to fix + + #if 0 + + sprintf(pcName, + "IEEE 802.11%s", + (eNetWorkType == NETWORK_TYPE_OFDM24) ? "g/n" : "b"); + + #endif + } + 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; + } + else { + /* 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(INIT, INFO, ("%s(): Set UNSUPPORTED Mode = %d.\n", __FUNCTION__, *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; + + 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(INIT, INFO, ("%s(): Get UNKNOWN Mode.\n", __FUNCTION__)); + 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); + 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(INIT, INFO, ("[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; + } + else { + DBGLOG(INIT, INFO, ("[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(INIT, INFO, ("[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(INIT, INFO, ("[wifi] no memory for larger scan list :%ld\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(INIT, INFO, ("[wifi] larger buf:%d result:%ld\n", u4AllocBufLen, u4BufLen)); + ret = -E2BIG; + prData->length = (__u16)u4BufLen; + goto error; + } +#endif /* WIRELESS_EXT >= 17 */ + + } + + + if (prList->u4NumberOfItems > CFG_MAX_NUM_BSS_LIST) { + DBGLOG(INIT, INFO, ("[wifi] strange scan result count:%ld\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; + memcpy(iwEvent.u.ap_addr.sa_data, prBss->arMacAddress, ETH_ALEN); + 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 lengh 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; + } + else { + /* 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; + } + else { + 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; + + 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(INIT, INFO, ("######set disassoc failed\n")); + } else { + DBGLOG(INIT, INFO, ("######set assoc ok\n")); + } + + /* <2> mark to power state flag*/ + ePowerState = ACPI_STATE_D0; + DBGLOG(INIT, INFO, ("set to acpi d3(0)\n")); + wlanSetAcpiState(prGlueInfo->prAdapter, ePowerState); + + } + else { + ePowerState = ACPI_STATE_D0; + DBGLOG(INIT, 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; + + 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(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\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(INIT, INFO, ("%s(): unsupported power management mode value = %d.\n", + __FUNCTION__, + 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(INIT, 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(INIT, 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; + } + +//#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 * 2); + + /* 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) { + //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:[" MACSTR "]\n", + prRemoveKey->KeyIndex, MAC2STR(prRemoveKey->BSSID)); + */ + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetRemoveKey, + prRemoveKey, + prRemoveKey->u4Length, + FALSE, + FALSE, + TRUE, + FALSE, + &u4BufLen); + + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(INIT, INFO, ("remove key error:%lx\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(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\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(INIT, INFO, ("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) { + DBGLOG(INIT, INFO, ("wlanoidSetEncryptionStatus fail 0x%lx\n", rStatus)); + return -EFAULT; + } + + } else { + DBGLOG(INIT, INFO, ("key length %x\n", prIWEncExt->key_len)); + DBGLOG(INIT, 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(INIT, INFO, ("key index error:0x%lx\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; + } + + /* 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); + + /* 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(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 = ((UINT_32)&(((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(INIT, INFO, ("add key error:%lx\n", rStatus)); + return -EFAULT; + } + break; + } + } + + return 0; +} /* wext_set_encode_ext */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Set country code +* +* \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_country ( + IN struct net_device *prNetDev, + IN struct iwreq *iwr + ) +{ + P_GLUE_INFO_T prGlueInfo; + WLAN_STATUS rStatus; + UINT_32 u4BufLen; + UINT_8 aucCountry[2]; + + ASSERT(prNetDev); + + /* iwr->u.data.pointer should be like "COUNTRY US", "COUNTRY EU" + * and "COUNTRY JP" + */ + if (FALSE == GLUE_CHK_PR2(prNetDev, iwr) || + !iwr->u.data.pointer || iwr->u.data.length < 10) { + return -EINVAL; + } + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prNetDev); + + aucCountry[0] = *((PUINT_8)iwr->u.data.pointer + 8); + aucCountry[1] = *((PUINT_8)iwr->u.data.pointer + 9); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetCountryCode, + &aucCountry[0], + 2, + FALSE, + FALSE, + TRUE, + FALSE, + &u4BufLen); + + return 0; +} + +/*----------------------------------------------------------------------------*/ +/*! +* \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 + ) +{ + /* prIfReq is verified in the caller function wlanDoIOCTL() */ + struct iwreq *iwr = (struct iwreq*)prIfReq; + struct iw_request_info rIwReqInfo; + int ret = 0; + char *prExtraBuf = NULL; + UINT_32 u4ExtraSize = 0; + + /* prDev is verified in the caller function wlanDoIOCTL() */ + + //printk("%d CMD:0x%x\n", jiffies_to_msecs(jiffies), i4Cmd); + + /* Prepare the call */ + 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 shoule 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, Country */ + ret = wext_set_country(prDev, iwr); + break; + + /* case SIOCGIWPRIV: 0x8B0D, handled in wlan_do_ioctl() */ + /* caes 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; + } + else { + 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(INIT, INFO, ("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(INIT, INFO, ("[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(INIT, INFO, ("Updated result length is larger than allocated (%d > %ld)\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(INIT, INFO, ("[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) { + P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)netdev_priv(prDev); + if (1 /* wlanQueryWapiMode(prGlueInfo->prAdapter) */) { + /* 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) { + 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 { + WLAN_STATUS rStatus; + UINT_32 u4BufLen; +#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 [" MACSTR "]\n", + MAC2STR(((struct iw_pmksa *)pExtraBuf)->bssid.sa_data)); + */ + { + P_GLUE_INFO_T prGlueInfo = + (P_GLUE_INFO_T)netdev_priv(prDev); + WLAN_STATUS rStatus; + UINT_32 u4BufLen; + P_PARAM_PMKID_T prPmkid; + + prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE); + if (!prPmkid) { + DBGLOG(INIT, INFO, ("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(INIT, INFO, ("add pmkid error:%lx\n", rStatus)); + } + kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T)); + } + break; + case IW_PMKSA_REMOVE: + /* + printk(KERN_INFO "IW_PMKSA_REMOVE [" MACSTR "]\n", + MAC2STR(((struct iw_pmksa *)buf)->bssid.sa_data)); + */ + break; + case IW_PMKSA_FLUSH: + /* + printk(KERN_INFO "IW_PMKSA_FLUSH\n"); + */ + { + P_GLUE_INFO_T prGlueInfo = + (P_GLUE_INFO_T)netdev_priv(prDev); + WLAN_STATUS rStatus; + UINT_32 u4BufLen; + P_PARAM_PMKID_T prPmkid; + + prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8, VIR_MEM_TYPE); + if (!prPmkid) { + DBGLOG(INIT, INFO, ("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(INIT, INFO, ("flush pmkid error:%lx\n", rStatus)); + } + kalMemFree(prPmkid, VIR_MEM_TYPE, 8); + } + break; + default: + DBGLOG(INIT, INFO, ("UNKNOWN iw_pmksa command:%d\n", + ((struct iw_pmksa *)prExtraBuf)->cmd)); + ret = -EFAULT; + break; + } + } + + if (prExtraBuf) { + kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize); + prExtraBuf = NULL; + } + } + else if (iwr->u.data.length != 0) { + ret = -EINVAL; + break; + } + #endif + break; + +#endif + + default: + /* printk(KERN_NOTICE "unsupported IOCTL: 0x%x\n", i4Cmd); */ + ret = -EOPNOTSUPP; + break; + } + + //printk("%ld CMD:0x%x ret:%d\n", jiffies_to_msecs(jiffies), i4Cmd, ret); + + return ret; +} /* wext_support_ioctl */ + + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief To send an event (RAW socket pacekt) to user process actively. +* +* \param[in] prGlueInfo Glue layer info. +* \param[in] u4cmd Whcih event command we want to indicate to user process. +* \param[in] pData Data buffer to be indicated. +* \param[in] dataLen Available data size in pData. +* +* \return (none) +* +* \note Event is indicated to upper layer if cmd is supported and data is valid. +* Using of kernel symbol wireless_send_event(), which is defined in +* after WE-14 (2.4.20). +*/ +/*----------------------------------------------------------------------------*/ +void +wext_indicate_wext_event ( + IN P_GLUE_INFO_T prGlueInfo, + IN unsigned int u4Cmd, + IN unsigned char *pucData, + IN unsigned int u4dataLen + ) +{ + union iwreq_data wrqu; + unsigned char *pucExtraInfo = NULL; +#if WIRELESS_EXT >= 15 + unsigned char *pucDesiredIE = NULL; + unsigned char aucExtraInfoBuf[200]; +#endif +#if WIRELESS_EXT < 18 + int i; +#endif + + memset(&wrqu, 0, sizeof(wrqu)); + + switch (u4Cmd) { + case SIOCGIWTXPOW: + memcpy(&wrqu.power, pucData, u4dataLen); + break; + case SIOCGIWSCAN: + complete_all(&prGlueInfo->rScanComp); + break; + + case SIOCGIWAP: + if (pucData) { + 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 */ + } +#if 0 + else if (wextSrchDesiredWPSIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { + /* WPS IE found */ + } +#endif + else if (wextSrchDesiredWPAIE(pucData, u4dataLen, 0xDD, &pucDesiredIE)) { + /* WPA IE found */ + } +#if CFG_SUPPORT_WAPI /* Android+ */ + else if (wextSrchDesiredWAPIIE(pucData, u4dataLen, &pucDesiredIE)) { + //printk("wextSrchDesiredWAPIIE!!\n"); + /* WAPI IE found */ + } +#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; + 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 */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief To report the private supported IOCTLs table to user space. +* +* \param[in] prNetDev Net device requested. +* \param[out] prIfReq Pointer to ifreq structure, content is copied back to +* user space buffer in gl_iwpriv_table. +* +* \retval 0 For success. +* \retval -E2BIG For user's buffer size is too small. +* \retval -EFAULT For fail. +* +*/ +/*----------------------------------------------------------------------------*/ +int +wext_get_priv ( + IN struct net_device *prNetDev, + IN struct ifreq *prIfReq + ) +{ + /* prIfReq is verified in the caller function wlanDoIOCTL() */ + struct iwreq *prIwReq = (struct iwreq *)prIfReq; + struct iw_point *prData= (struct iw_point *)&prIwReq->u.data; + UINT_16 u2BufferSize = 0; + + u2BufferSize = prData->length; + + /* update our private table size */ + prData->length = (__u16)sizeof(rIwPrivTable)/sizeof(struct iw_priv_args); + + 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 */ + +#endif /* WIRELESS_EXT */ + + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext_priv.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext_priv.c new file mode 100755 index 000000000000..c7c4fb150e1a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/gl_wext_priv.c @@ -0,0 +1,2292 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/gl_wext_priv.c#1 $ +*/ + +/*! \file gl_wext_priv.c + \brief This file includes private ioctl support. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_wext_priv.c $ + * + * 02 06 2012 wh.su + * [ALPS00109161] [Need Patch] [Volunteer Patch] [Wi-Fi] Support the set tx power driver cmd + * Adding the AP mode channel query filter. + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 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 03 2011 chinghwa.yu + * [WCXRP00000063] Update BCM CoEx design and settings + * Fixed typo. + * + * 10 24 2011 terry.wu + * NULL + * Rollback to previous verson due to misbranch check-in + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 supress 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 "gl_os.h" +#include "gl_wext_priv.h" +#if CFG_SUPPORT_WAPI +#include "gl_sec.h" +#endif + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define NUM_SUPPORTED_OIDS (sizeof(arWlanOidReqTable) / sizeof(WLAN_REQ_ENTRY)) + +/******************************************************************************* +* 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_STRUC_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_STRUC_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_STRUC_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_STRUC_T), + (PFN_OID_HANDLER_FUNC_REQ)wlanoidQuerySwCtrlRead, + (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetSwCtrlWrite}, + + {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_STRUC_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_STRUC_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_STRUC_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 */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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. +* +*/ +/*----------------------------------------------------------------------------*/ +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_STRUC_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_STRUC_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 = %d.\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 : PRIV_CUSTOM_BWCS_CMD : aucBTPParams[0] = %02x, aucBTPParams[1] = %02x, aucBTPParams[2] = %02x, aucBTPParams[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; + + 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. +* +*/ +/*----------------------------------------------------------------------------*/ +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; + 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->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; + break; + } + + 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_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: + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQueryBeaconInterval, + (PVOID)pu4IntBuf, + sizeof(UINT_32), + &u4BufLen); + break; + + case PRIV_CMD_POWER_MODE: + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQuery802dot11PowerSaveProfile, + (PVOID)pu4IntBuf, + sizeof(UINT_32), + &u4BufLen); + break; + + case PRIV_CMD_ADHOC_MODE: + rStatus = wlanQueryInformation(prGlueInfo->prAdapter, + wlanoidQueryAdHocMode, + (PVOID)pu4IntBuf, + sizeof(UINT_32), + &u4BufLen); + break; + #endif + + 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; + RF_CHANNEL_INFO_T aucChannelList[50]; + + kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList); + if (NumOfChannel > 50) + NumOfChannel = 50; + + if (kalIsAPmode(prGlueInfo)) { + for (i = 0; i < NumOfChannel; i++) { + if ((aucChannelList[i].ucChannelNum <= 13) || + (aucChannelList[i].ucChannelNum == 36 || aucChannelList[i].ucChannelNum == 40 || + aucChannelList[i].ucChannelNum == 44 || aucChannelList[i].ucChannelNum == 48)) { + ch[j] = (INT_32)aucChannelList[i].ucChannelNum; + j++; + } + } + } + else { + for (j = 0; j < NumOfChannel; j++) { + ch[j] = (INT_32)aucChannelList[j].ucChannelNum; + } + } + + prIwReqData->data.length = j; + if (copy_to_user(prIwReqData->data.pointer, ch, NumOfChannel*sizeof(INT_32))) { + 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. +* +*/ +/*----------------------------------------------------------------------------*/ +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 + printk("Tx power num = %d\n", prIwReqData->data.length); + + printk("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. +* +*/ +/*----------------------------------------------------------------------------*/ +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]; + + kalGetChannelList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList); + if (NumOfChannel > 50) + NumOfChannel = 50; + + for (i = 0; i < NumOfChannel; i++) { + ch[i] = (INT_32)aucChannelList[i].ucChannelNum; + } + + 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. +* +*/ +/*----------------------------------------------------------------------------*/ +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 + printk(KERN_INFO DRV_NAME"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(%ld)\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 +#if CFG_SUPPORT_WAPI + case PRIV_SEC_MSG_OID: + { + int msg_in_len =0; + int msg_out_len = 0; + unsigned char msg_out[1000]; + + DBGLOG(WAPI, TRACE, ("Set msg private ioctl!!!\n")); + + if (copy_from_user(&aucOidBuf[0], + prIwReqData->data.pointer, + prIwReqData->data.length)) { //+2 + status = -EFAULT; + break; + } + msg_in_len = prIwReqData->data.length; + + if(aucOidBuf[0] == 0x01) { + + handle_sec_msg_1(aucOidBuf, msg_in_len, msg_out , &msg_out_len); + + prIwReqData->data.length = msg_out_len; + if (copy_to_user(prIwReqData->data.pointer, + &(prIwReqData->data.length), + sizeof(__u16))) { + DBGLOG(REQ, INFO, ("copy_to_user oidBuf fail\n")); + status = -EFAULT; + break; + } + + if (copy_to_user((char *)prIwReqData->data.pointer + sizeof(__u16), + &msg_out[0], + prIwReqData->data.length)) { + DBGLOG(REQ, INFO, ("copy_to_user oidBuf fail\n")); + status = -EFAULT; + break; + } + + } + else if(aucOidBuf[0] == 0x02){ + + handle_sec_msg_2(aucOidBuf, msg_in_len, msg_out , &msg_out_len); + + prIwReqData->data.length = 0; + if (copy_to_user(prIwReqData->data.pointer, + &(prIwReqData->data.length), + sizeof(__u16))) { + DBGLOG(REQ, INFO, ("copy_to_user oidBuf fail\n")); + status = -EFAULT; + break; + } + } + else if(aucOidBuf[0] == 0x03){ + + handle_sec_msg_3(aucOidBuf, msg_in_len, msg_out , &msg_out_len); + + prIwReqData->data.length = 0; + if (copy_to_user(prIwReqData->data.pointer, + &(prIwReqData->data.length), + sizeof(__u16))) { + DBGLOG(REQ, INFO, ("copy_to_user oidBuf fail\n")); + status = -EFAULT; + break; + } + } + else if(aucOidBuf[0] == 0x04){ + + handle_sec_msg_4(aucOidBuf, msg_in_len, msg_out , &msg_out_len); + + prIwReqData->data.length = 0; + if (copy_to_user(prIwReqData->data.pointer, + &(prIwReqData->data.length), + sizeof(__u16))) { + DBGLOG(REQ, INFO, ("copy_to_user oidBuf fail\n")); + status = -EFAULT; + break; + } + } + else if(aucOidBuf[0] == 0x05){ + + handle_sec_msg_5(aucOidBuf, msg_in_len, msg_out , &msg_out_len); + + prIwReqData->data.length = 0; + if (copy_to_user(prIwReqData->data.pointer, + &(prIwReqData->data.length), + sizeof(__u16))) { + DBGLOG(REQ, INFO, ("copy_to_user oidBuf fail\n")); + status = -EFAULT; + break; + } + } + + } + 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. +* +*/ +/*----------------------------------------------------------------------------*/ +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, netdev_priv(prNetDev))); + return -EINVAL; + } + +#if 0 + printk(KERN_INFO DRV_NAME"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 + printk(KERN_NOTICE "\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; + } + else { + 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; + } + break; + + 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; + break; + + default: + DBGLOG(REQ, WARN, ("get struct cmd:0x%lx\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, netdev_priv(prNetDev))); + return -EINVAL; + } + +#if 0 + printk(KERN_INFO DRV_NAME"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 + printk(KERN_INFO DRV_NAME"priv_set_ndis(): %s\n", + prWlanReqEntry->pucOidName + ); +#endif + + if (prWlanReqEntry->fgSetBufLenChecking) { + if (prNdisReq->inNdisOidlength != prWlanReqEntry->u4InfoBufLen) { + DBGLOG(REQ, WARN, ("Set %s: Invalid length (current=%ld, needed=%ld)\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, netdev_priv(prNetDev))); + return -EINVAL; + } + +#if 0 + printk(KERN_INFO DRV_NAME"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 + printk(KERN_INFO DRV_NAME"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 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; +} + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/arm.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/arm.c new file mode 100755 index 000000000000..eef362e4ffc3 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/arm.c @@ -0,0 +1,68 @@ +/****************************************************************************** +*[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. +******************************************************************************/ + + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: mt6516-evb.c $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif.h new file mode 100755 index 000000000000..6f71eff4232a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif.h @@ -0,0 +1,269 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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 +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: hif.h $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + + +#if MTK_WCN_HIF_SDIO +#include "hif_sdio.h" +#endif + +/******************************************************************************* +* C O M P I L E 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 SDIO_X86_WORKAROUND_WRITE_MCR 0x00C4 + +/******************************************************************************* +* 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_INFO_T { +#if MTK_WCN_HIF_SDIO + MTK_WCN_HIF_SDIO_CLTCTX cltCtx; + const MTK_WCN_HIF_SDIO_FUNCINFO *prFuncInfo; +#else + struct sdio_func *func; +#endif + BOOLEAN fgIntReadClear; + BOOLEAN fgMbxReadClear; +} GL_HIF_INFO_T, *P_GL_HIF_INFO_T; + + +#if CFG_DBG_GPIO_PINS + +extern void +mtk_wcn_stp_debug_gpio_assert(UINT_32 dwIndex, UINT_32 dwMethod); + + +/* Platform DEPENDENT configurations: MT6516 GPIO pin name */ +#define GPIO_6516(x) (GPIO##x) +#define GPIO_PLATFORM(x) GPIO_6516(x) + +/* Platform independent configurations */ +#define DBG_TIE_DIR 0x40000000UL +#define DBG_LOW 0x0UL +#define DBG_HIGH 0x1UL +#define DBG_TIE_LOW (DBG_TIE_DIR | DBG_LOW) +#define DBG_TIE_HIGH (DBG_TIE_DIR | DBG_HIGH) + +#define DBG_TOGGLE(x) (0x80000000UL | x) +#define DBG_TOGGLE_NUM(x) (x & 0xFFF) +#define GPIO_INVALID 0xFFFF + +typedef enum { + IDX_ERR = 0, + IDX_TX_THREAD, + IDX_TX_REQ, + IDX_TX_PORT_WRITE, + IDX_STP_MTX_BT, + IDX_STP_MTX_FM, /* 5 */ + IDX_STP_MTX_GPS, + IDX_STP_MTX_WIFI, + IDX_STP_MTX_WMT, + IDX_LOOP_CNT, + IDX_NO_BUF, /*10 */ + IDX_BT_TX, + IDX_BT_RX, + IDX_GPS_RX, + IDX_GPS_2, + IDX_GPS_3, + IDX_GPS_TX, + IDX_STP_MAX +} DBG_PIN; + +#define DBG_MTX_OFFSET (IDX_STP_MTX_BT) /* index of mutex0 */ +#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 +******************************************************************************** +*/ + +WLAN_STATUS +glRegisterBus( + probe_card pfProbe, + remove_card pfRemove + ); + +VOID +glUnregisterBus( + remove_card pfRemove + ); + +VOID +glSetHifInfo ( + P_GLUE_INFO_T prGlueInfo, + UINT_32 u4Cookie + ); + +VOID +glClearHifInfo ( + P_GLUE_INFO_T prGlueInfo + ); + +BOOL +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 + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_H */ diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif_sdio.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif_sdio.h new file mode 100755 index 000000000000..c444fe1214b0 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/hif_sdio.h @@ -0,0 +1,311 @@ + +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/hif/sdio/include/hif_sdio.h#2 $ +*/ + +/*! \file "hif_sdio.h" + \brief + + +*/ + +/* +** $Log: $ + * + * 01 09 2012 terry.wu + * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork + * cfg80211 integration for p2p network. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 08 18 2010 jeffrey.chang + * NULL + * support multi-function sdio + * + * 07 25 2010 george.kuo + * + * Move hif_sdio driver to linux directory. + * + * 07 23 2010 george.kuo + * + * Add MT6620 driver source tree + * , including char device driver (wmt, bt, gps), stp driver, interface driver (tty ldisc and hif_sdio), and bt hci driver. +** +** +*/ + +#ifndef _HIF_SDIO_H +#define _HIF_SDIO_H +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ +#define HIF_SDIO_DEBUG (0) /* 0:trun off debug msg and assert, 1:trun off debug msg and assert */ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include "mtk_porting.h" + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define CFG_CLIENT_COUNT (9) + +#define HIF_DEFAULT_BLK_SIZE (256) +#define HIF_DEFAULT_VENDOR (0x037A) + +#define HIF_SDIO_LOG_LOUD 4 +#define HIF_SDIO_LOG_DBG 3 +#define HIF_SDIO_LOG_INFO 2 +#define HIF_SDIO_LOG_WARN 1 +#define HIF_SDIO_LOG_ERR 0 + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ + +/* Function info provided by client driver */ +typedef struct _MTK_WCN_HIF_SDIO_FUNCINFO MTK_WCN_HIF_SDIO_FUNCINFO; + +/* Client context provided by hif_sdio driver for the following function call */ +typedef UINT32 MTK_WCN_HIF_SDIO_CLTCTX; + +/* Callback functions provided by client driver */ +typedef INT32 (*MTK_WCN_HIF_SDIO_PROBE)(MTK_WCN_HIF_SDIO_CLTCTX, const MTK_WCN_HIF_SDIO_FUNCINFO *); +typedef INT32 (*MTK_WCN_HIF_SDIO_REMOVE)(MTK_WCN_HIF_SDIO_CLTCTX); +typedef INT32 (*MTK_WCN_HIF_SDIO_IRQ)(MTK_WCN_HIF_SDIO_CLTCTX); + +/* Function info provided by client driver */ +struct _MTK_WCN_HIF_SDIO_FUNCINFO { + UINT16 manf_id; /* TPLMID_MANF: manufacturer ID */ + UINT16 card_id; /* TPLMID_CARD: card ID */ + UINT16 func_num; /* Function Number */ + UINT16 blk_sz; /* Function block size */ +}; + +/* Client info provided by client driver */ +typedef struct _MTK_WCN_HIF_SDIO_CLTINFO { + const MTK_WCN_HIF_SDIO_FUNCINFO *func_tbl; /* supported function info table */ + UINT32 func_tbl_size; /* supported function table info element number */ + MTK_WCN_HIF_SDIO_PROBE hif_clt_probe; /* callback function for probing */ + MTK_WCN_HIF_SDIO_REMOVE hif_clt_remove; /* callback function for removing */ + MTK_WCN_HIF_SDIO_IRQ hif_clt_irq; /* callback function for interrupt handling */ +} MTK_WCN_HIF_SDIO_CLTINFO; + +/* function info provided by registed function */ +typedef struct _MTK_WCN_HIF_SDIO_REGISTINFO { + const MTK_WCN_HIF_SDIO_CLTINFO *sdio_cltinfo; /* client's MTK_WCN_HIF_SDIO_CLTINFO pointer */ + const MTK_WCN_HIF_SDIO_FUNCINFO *func_info; /* supported function info pointer */ +} MTK_WCN_HIF_SDIO_REGISTINFO; + +/* Card info provided by probed function */ +typedef struct _MTK_WCN_HIF_SDIO_PROBEINFO { + struct sdio_func* func; /* probed sdio function pointer */ + void* private_data_p; /* clt's private data pointer */ + MTK_WCN_BOOL on_by_wmt; /* TRUE: on by wmt, FALSE: not on by wmt */ + /* added for sdio irq sync and mmc single_irq workaround */ + MTK_WCN_BOOL sdio_irq_enabled; /* TRUE: can handle sdio irq; FALSE: no sdio irq handling */ + INT8 clt_idx; /* registered function table info element number (initial value is -1) */ +} MTK_WCN_HIF_SDIO_PROBEINFO; + +/* work queue info needed by worker */ +typedef struct _MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO { + struct work_struct probe_work; /* work queue structure */ + MTK_WCN_HIF_SDIO_REGISTINFO *registinfo_p; /* MTK_WCN_HIF_SDIO_REGISTINFO pointer of the client */ + INT8 probe_idx; /* probed function table info element number (initial value is -1) */ +} MTK_WCN_HIF_SDIO_CLT_PROBE_WORKERINFO; + +/* error code returned by hif_sdio driver (use NEGATIVE number) */ +typedef enum { + HIF_SDIO_ERR_SUCCESS = 0, + HIF_SDIO_ERR_FAIL = HIF_SDIO_ERR_SUCCESS - 1, /* generic error */ + HIF_SDIO_ERR_INVALID_PARAM = HIF_SDIO_ERR_FAIL - 1, + HIF_SDIO_ERR_DUPLICATED = HIF_SDIO_ERR_INVALID_PARAM - 1, + HIF_SDIO_ERR_UNSUP_MANF_ID = HIF_SDIO_ERR_DUPLICATED - 1, + HIF_SDIO_ERR_UNSUP_CARD_ID = HIF_SDIO_ERR_UNSUP_MANF_ID - 1, + HIF_SDIO_ERR_INVALID_FUNC_NUM = HIF_SDIO_ERR_UNSUP_CARD_ID - 1, + HIF_SDIO_ERR_INVALID_BLK_SZ = HIF_SDIO_ERR_INVALID_FUNC_NUM - 1, + HIF_SDIO_ERR_NOT_PROBED = HIF_SDIO_ERR_INVALID_BLK_SZ - 1, + HIF_SDIO_ERR_ALRDY_ON = HIF_SDIO_ERR_NOT_PROBED -1, + HIF_SDIO_ERR_ALRDY_OFF = HIF_SDIO_ERR_ALRDY_ON -1, + HIF_SDIO_ERR_CLT_NOT_REG = HIF_SDIO_ERR_ALRDY_OFF - 1, +} MTK_WCN_HIF_SDIO_ERR ; + +/******************************************************************************* +* P U B L I C D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* P R I V A T E D A T A +******************************************************************************** +*/ + +/******************************************************************************* +* M A C R O S +******************************************************************************** +*/ + +/*! + * \brief A macro used to describe an SDIO function + * + * Fill an MTK_WCN_HIF_SDIO_FUNCINFO structure with function-specific information + * + * \param manf the 16 bit manufacturer id + * \param card the 16 bit card id + * \param func the 16 bit function number + * \param b_sz the 16 bit function block size + */ +#define MTK_WCN_HIF_SDIO_FUNC(manf, card, func, b_sz) \ + .manf_id = (manf), .card_id = (card), .func_num = (func), .blk_sz = (b_sz) + +#define HIF_SDIO_LOUD_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_LOUD) { printk(KERN_INFO SDIO_TAG"[L]%s:" fmt, __FUNCTION__ ,##arg);} +#define HIF_SDIO_DBG_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_DBG) { printk(KERN_INFO SDIO_TAG"[D]%s:" fmt, __FUNCTION__ ,##arg);} +#define HIF_SDIO_INFO_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_INFO) { printk(KERN_INFO SDIO_TAG"[I]%s:" fmt, __FUNCTION__ ,##arg);} +#define HIF_SDIO_WARN_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_WARN) { printk(KERN_WARNING SDIO_TAG"[W]%s(%d):" fmt, __FUNCTION__ , __LINE__, ##arg);} +#define HIF_SDIO_ERR_FUNC(fmt, arg...) if (gHifSdioDbgLvl >= HIF_SDIO_LOG_ERR) { printk(KERN_WARNING SDIO_TAG"[E]%s(%d):" fmt, __FUNCTION__ , __LINE__, ##arg);} + +/*! + * \brief ASSERT function definition. + * + */ +#if HIF_SDIO_DEBUG +#define HIF_SDIO_ASSERT(expr) if ( !(expr) ) { \ + printk("assertion failed! %s[%d]: %s\n",\ + __FUNCTION__, __LINE__, #expr); \ + BUG_ON( !(expr) );\ + } +#else +#define HIF_SDIO_ASSERT(expr) do {} while(0) +#endif + +/******************************************************************************* +* F U N C T I O N D E C L A R A T I O N S +******************************************************************************** +*/ + +/*! + * \brief MTK hif sdio client registration function + * + * Client uses this function to do hif sdio registration + * + * \param pinfo a pointer of client's information + * + * \retval 0 register successfully + * \retval < 0 error code + */ +extern INT32 mtk_wcn_hif_sdio_client_reg ( + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo + ); + +extern INT32 mtk_wcn_hif_sdio_client_unreg ( + const MTK_WCN_HIF_SDIO_CLTINFO *pinfo + ); + +extern INT32 mtk_wcn_hif_sdio_readb ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT8 pvb + ); + +extern INT32 mtk_wcn_hif_sdio_writeb ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + UINT8 vb + ); + +extern INT32 mtk_wcn_hif_sdio_readl ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pvl + ); + +extern INT32 mtk_wcn_hif_sdio_writel ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + UINT32 vl + ); + +extern INT32 mtk_wcn_hif_sdio_read_buf ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pbuf, + UINT32 len + ); + +extern INT32 mtk_wcn_hif_sdio_write_buf ( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + UINT32 offset, + PUINT32 pbuf, + UINT32 len + ); + +extern void mtk_wcn_hif_sdio_set_drvdata( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + void* private_data_p + ); + +extern void* mtk_wcn_hif_sdio_get_drvdata( + MTK_WCN_HIF_SDIO_CLTCTX ctx + ); + +extern void mtk_wcn_hif_sdio_get_dev( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + struct device **dev + ); + +extern void mtk_wcn_hif_sdio_enable_irq( + MTK_WCN_HIF_SDIO_CLTCTX ctx, + MTK_WCN_BOOL enable + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ +#endif /* _HIF_SDIO_H */ + + + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/mtk_porting.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/mtk_porting.h new file mode 100755 index 000000000000..de75f1d83369 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/include/mtk_porting.h @@ -0,0 +1,53 @@ + +/* porting layer */ +/* Android */ + +#ifndef _MTK_PORTING_H_ +#define _MTK_PORTING_H_ + +#include /* include stddef.h for NULL */ + +/* Type definition for signed integers */ +typedef signed char INT8, *PINT8; +typedef signed short INT16, *PINT16; +typedef signed int INT32, *PINT32; + +/* Type definition for unsigned integers */ +typedef unsigned char UINT8, *PUINT8; +typedef unsigned short UINT16, *PUINT16; +typedef unsigned int UINT32, *PUINT32; + +//typedef void VOID, *PVOID; + +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 INT32 (*MUTEX_DESTROY)(MTK_WCN_MUTEX mtx); +typedef INT32 (*MUTEX_LOCK)(MTK_WCN_MUTEX mtx); +typedef INT32 (*MUTEX_UNLOCK)(MTK_WCN_MUTEX mtx, unsigned long flags); +/* debug */ +typedef INT32 (*DBG_PRINT)(const char *str, ...); +typedef INT32 (*DBG_ASSERT)(INT32 expr, const char *file, INT32 line); +/* timer */ +typedef void (*MTK_WCN_TIMER_CB)(void); +typedef MTK_WCN_TIMER (*TIMER_CREATE)(const char * const name); +typedef INT32 (*TIMER_DESTROY)(MTK_WCN_TIMER tmr); +typedef INT32 (*TIMER_START)(MTK_WCN_TIMER tmr, UINT32 timeout, MTK_WCN_TIMER_CB tmr_cb, void *param); +typedef INT32 (*TIMER_STOP)(MTK_WCN_TIMER tmr); +/* kernel lib */ +typedef void* (*SYS_MEMCPY)(void *dest, const void *src, UINT32 n); +typedef void* (*SYS_MEMSET)(void *s, INT32 c, UINT32 n); +typedef INT32 (*SYS_SPRINTF)(char *str, const char *format, ...); + +#endif /* _MTK_PORTING_H_ */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/sdio.S b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/sdio.S new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/sdio.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/sdio.c new file mode 100755 index 000000000000..3556546a66c5 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/sdio.c @@ -0,0 +1,1281 @@ +/****************************************************************************** +*[File] sdio.c +*[Version] v1.0 +*[Revision Date] 2010-03-01 +*[Author] +*[Description] +* The program provides SDIO HIF driver +*[Copyright] +* Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved. +******************************************************************************/ + + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: sdio.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. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 "gl_os.h" + +#if MTK_WCN_HIF_SDIO +#include "hif_sdio.h" +#else +#include +#include +#include +#include /* sdio_readl(), etc */ +#include +#endif + +#include +//#ifndef CONFIG_X86 modify by Nicolas Luo +#ifdef CONFIG_ARM +#include +#endif +#include "mt6620_reg.h" + +#if CFG_DBG_GPIO_PINS/* FIXME: move to platform or custom header */ +#include +#endif + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ + +#if MTK_WCN_HIF_SDIO + + +/* + * function prototypes + * + */ + +static INT32 +mtk_sdio_probe(MTK_WCN_HIF_SDIO_CLTCTX, const MTK_WCN_HIF_SDIO_FUNCINFO *); + +static INT32 +mtk_sdio_remove(MTK_WCN_HIF_SDIO_CLTCTX); +static INT32 mtk_sdio_interrupt(MTK_WCN_HIF_SDIO_CLTCTX); + +/* + * sdio function info table + */ + +static MTK_WCN_HIF_SDIO_FUNCINFO funcInfo[] = { +#if defined(MT6620) + { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x020a, 0x1, 512) }, + { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x020c, 0x2, 512) }, + { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x018a, 0x1, 512) }, + { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x018c, 0x2, 512) }, +#elif defined(MT5931) + { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x5931, 0x1, 512) }, +#elif defined(MT6628) + { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x6628, 0x1, 512) }, +#endif +}; + + +static MTK_WCN_HIF_SDIO_CLTINFO cltInfo = { + .func_tbl = funcInfo, + .func_tbl_size = sizeof(funcInfo)/sizeof(MTK_WCN_HIF_SDIO_FUNCINFO), + .hif_clt_probe = mtk_sdio_probe, + .hif_clt_remove = mtk_sdio_remove, + .hif_clt_irq = mtk_sdio_interrupt, +}; + +#else + +static const struct sdio_device_id mtk_sdio_ids[] = { +#if defined(MT6620) + { SDIO_DEVICE(0x037a, 0x020a) }, /* Not an SDIO standard class device */ + { SDIO_DEVICE(0x037a, 0x020b) }, /* Not an SDIO standard class device */ + { SDIO_DEVICE(0x037a, 0x020c) }, /* Not an SDIO standard class device */ +#elif defined(MT5931) + { SDIO_DEVICE(0x037a, 0x5931) }, /* Not an SDIO standard class device */ +#elif defined(MT6628) + { SDIO_DEVICE(0x037a, 0x6628) }, /* Not an SDIO standard class device */ +#endif + { /* end: all zeroes */ }, +}; + +MODULE_DEVICE_TABLE(sdio, mtk_sdio_ids); + +#endif + +/******************************************************************************* +* 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 probe_card pfWlanProbe = NULL; +static remove_card pfWlanRemove = NULL; + + +#if (MTK_WCN_HIF_SDIO == 0) +static struct sdio_driver mtk_sdio_driver = { + .name = "wlan", /* "MTK SDIO WLAN Driver" */ + .id_table = mtk_sdio_ids, + .probe = NULL, + .remove = NULL, +}; +#endif + + +#if CFG_DBG_GPIO_PINS + +/* debug pins */ +UINT_32 dbgPinSTP[] = { + GPIO_PLATFORM(33)/* CMFLASH, IDX_ERR J613 */ + , GPIO_PLATFORM(62)/* EINT3, IDX_TX_THREAD */ + , GPIO_PLATFORM(80)/* SPI_CS_N, IDX_TX_REQ J613 */ + , GPIO_PLATFORM(81)/* SPI_SCK, IDX_TX_PORT_WRITE J613 */ + , GPIO_PLATFORM(17) /* CMRST, IDX_STP_MTX_BT J618 */ + , GPIO_PLATFORM(18) /* CMPDN, IDX_STP_MTX_FM J613 */ + , GPIO_PLATFORM(19) /* CMVREF,IDX_STP_MTX_GPS J613 */ + , GPIO_INVALID /* REMOVED, IDX_STP_MTX_WIFI */ + , GPIO_INVALID /* REMOVED, IDX_STP_MTX_WMT */ + , GPIO_PLATFORM(135) /* SCL2, IDX_LOOP_CNT J616 */ + , GPIO_PLATFORM(136) /* SDA2, IDX_NO_BUF J616 */ + , GPIO_PLATFORM(30) /* CAM_MECHSH0, IDX_BT_TX, J613 low-active */ + , GPIO_PLATFORM(31) /* CAM_MECHSH1, IDX_BT_RX, J613 low-active */ + , GPIO_PLATFORM(124) /* GPS_PWR_EN, ThreadDSPIn [GPS] */ + , GPIO_PLATFORM(125) /* GPS_SYNC, mtk_sys_msg_recv [GPS] */ + , GPIO_PLATFORM(21) /* GPS_EINT8, dump_nmea_data [GPS] */ + , GPIO_PLATFORM(29) /* CAM_STROBE, IDX_GPS_TX, J613 low-active */ + , GPIO_PLATFORM(20) /*CMHREF, J613 UNUSED */ +// , GPIO_6516(64) /* EINT5, REMOVED!!! for MT6620-Wi-Fi Int */ +// , GPIO_6516(122) /* BT_PWR_EN, REMOVED!!! for MT6620-PMU_EN */ +// , GPIO_6516(123) /* BT_RESET, REMOVED!!! for MT6620-RST */ +}; +#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 +******************************************************************************** +*/ +#if CFG_DBG_GPIO_PINS +void debug_gpio_init(void) +{ + int i; + + for (i = 0; i < sizeof(dbgPinSTP)/sizeof(dbgPinSTP[0]); ++i) { + if (GPIO_INVALID == dbgPinSTP[i]) { + continue; + } + //printk(KERN_INFO "[%s] %ld \n", __FUNCTION__, dbgPinSTP[i]); + mt_set_gpio_pull_enable(dbgPinSTP[i], 0); /* disable pull */ + mt_set_gpio_dir(dbgPinSTP[i], GPIO_DIR_OUT); /* set output */ + mt_set_gpio_mode(dbgPinSTP[i], GPIO_MODE_00); /* set gpio mode */ + + /* toggle twice to check if ok: */ + mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ZERO); /* tie low */ + mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ONE); /* tie high*/ + mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ZERO); /* tie low */ + mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ONE); /* tie high*/ + } + //printk(KERN_INFO "[%s] initialization ok \n", __FUNCTION__); +} + +void debug_gpio_deinit(void) +{ + int i; + for (i = 0; i < sizeof(dbgPinSTP)/sizeof(dbgPinSTP[0]); ++i) { + if (GPIO_INVALID == dbgPinSTP[i]) { + continue; + } + //printk(KERN_INFO "[%s] %ld \n", __FUNCTION__, dbgPinSTP[i]); + mt_set_gpio_dir(dbgPinSTP[i], GPIO_DIR_IN); + } + + //printk(KERN_INFO "[%s] k\n", __FUNCTION__); +} + +void mtk_wcn_stp_debug_gpio_assert(UINT_32 dwIndex, UINT_32 dwMethod) +{ + unsigned int i; + + if (dwIndex >= (sizeof(dbgPinSTP)/sizeof(dbgPinSTP[0]))) { + //printk(KERN_INFO "[%s] invalid dwIndex(%ld) \n", __FUNCTION__, dwIndex); + return; + } + + if (dwIndex > IDX_STP_MAX) { + //printk(KERN_INFO "[%s] dwIndex(%ld) > IDX_STP_MAX(%d) \n", __FUNCTION__, dwIndex, IDX_STP_MAX); + } + + if (GPIO_INVALID == dbgPinSTP[dwIndex]) { + return; + } + + if (dwMethod & DBG_TIE_DIR) { + if (dwMethod & DBG_HIGH) { + mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ONE); + } + else { + mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ZERO); + } + return; + } + + if (dwMethod & DBG_TOGGLE(0)) { + for (i = 0; i < DBG_TOGGLE_NUM(dwMethod); ++i) { + mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ZERO); + mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ONE); + } + return; + } + + return; +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function is a SDIO interrupt callback function +* +* \param[in] func pointer to SDIO handle +* +* \return void +*/ +/*----------------------------------------------------------------------------*/ + +#if MTK_WCN_HIF_SDIO + +static INT32 mtk_sdio_interrupt(MTK_WCN_HIF_SDIO_CLTCTX cltCtx) +{ + P_GLUE_INFO_T prGlueInfo = NULL; + INT32 ret = 0; + + prGlueInfo = mtk_wcn_hif_sdio_get_drvdata(cltCtx); + + ASSERT(prGlueInfo); + + if (!prGlueInfo) { + //printk(KERN_INFO DRV_NAME"No glue info in mtk_sdio_interrupt()\n"); + return (-HIF_SDIO_ERR_FAIL); + } + + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + //printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip INT\n"); + ret = mtk_wcn_hif_sdio_writel(cltCtx, MCR_WHLPCR, WHLPCR_INT_EN_CLR); + return ret; + } + + ret = mtk_wcn_hif_sdio_writel(cltCtx, MCR_WHLPCR, WHLPCR_INT_EN_CLR); + + set_bit (GLUE_FLAG_INT_BIT, &prGlueInfo->u4Flag); + + /* when we got sdio interrupt, we wake up the tx servie thread*/ + wake_up_interruptible(&prGlueInfo->waitq); + + return ret; +} + +#else + +static unsigned int in_interrupt = 0; + +static void mtk_sdio_interrupt(struct sdio_func *func) +{ + P_GLUE_INFO_T prGlueInfo = NULL; + + int ret = 0; + + prGlueInfo = sdio_get_drvdata(func); + ASSERT(prGlueInfo); + + if (!prGlueInfo) { + //printk(KERN_INFO DRV_NAME"No glue info in mtk_sdio_interrupt()\n"); + return; + } + + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + sdio_writel(prGlueInfo->rHifInfo.func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, &ret); + //printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip INT\n"); + return; + } + + sdio_writel(prGlueInfo->rHifInfo.func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, &ret); + + #if 0 + wlanISR(prGlueInfo->prAdapter, TRUE); + + if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { + /* Should stop now... skip pending interrupt */ + //printk(KERN_INFO DRV_NAME"ignore pending interrupt\n"); + } + else { + wlanIST(prGlueInfo->prAdapter); + } + #endif + + set_bit (GLUE_FLAG_INT_BIT, &prGlueInfo->u4Flag); + + /* when we got sdio interrupt, we wake up the tx servie thread*/ + wake_up_interruptible(&prGlueInfo->waitq); +} +#endif + +/*----------------------------------------------------------------------------*/ +/*! +* \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 MTK_WCN_HIF_SDIO + +// FIXME: global variable +static const MTK_WCN_HIF_SDIO_FUNCINFO *prFunc; + + +static INT32 +mtk_sdio_probe(MTK_WCN_HIF_SDIO_CLTCTX cltCtx, const MTK_WCN_HIF_SDIO_FUNCINFO *prFuncInfo) +{ + INT32 ret = HIF_SDIO_ERR_SUCCESS; + + prFunc = prFuncInfo; + + if (pfWlanProbe((PVOID) &cltCtx) != WLAN_STATUS_SUCCESS) { + //printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); + pfWlanRemove(); + ret = -(HIF_SDIO_ERR_FAIL); + } else { + //printk(KERN_INFO DRV_NAME"mtk_wifi_sdio_probe() done(%d)\n", ret); + } + return ret; +} +#else +static int mtk_sdio_probe ( + struct sdio_func *func, + const struct sdio_device_id *id + ) +{ + int ret = 0; + int i = 0; + + //printk(KERN_INFO DRV_NAME "mtk_sdio_probe()\n"); + + ASSERT(func); + ASSERT(id); + + //printk(KERN_INFO DRV_NAME "Basic struct size checking...\n"); + //printk(KERN_INFO DRV_NAME "sizeof(struct device) = %d\n", sizeof(struct device)); + //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_host) = %d\n", sizeof(struct mmc_host)); + //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_card) = %d\n", sizeof(struct mmc_card)); + //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_driver) = %d\n", sizeof(struct mmc_driver)); + //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_data) = %d\n", sizeof(struct mmc_data)); + //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_command) = %d\n", sizeof(struct mmc_command)); + //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_request) = %d\n", sizeof(struct mmc_request)); + //printk(KERN_INFO DRV_NAME "sizeof(struct sdio_func) = %d\n", sizeof(struct sdio_func)); + + //printk(KERN_INFO DRV_NAME "Card information checking...\n"); + //printk(KERN_INFO DRV_NAME "func = 0x%p\n", func); + //printk(KERN_INFO DRV_NAME "Number of info = %d:\n", func->card->num_info); + + for (i = 0; i < func->card->num_info; i++) { + //printk(KERN_INFO DRV_NAME "info[%d]: %s\n", i, func->card->info[i]); + } + + sdio_claim_host(func); + ret = sdio_enable_func(func); + sdio_release_host(func); + + if (ret) { + //printk(KERN_INFO DRV_NAME"sdio_enable_func failed!\n"); + goto out; + } + //printk(KERN_INFO DRV_NAME"sdio_enable_func done!\n"); + + if (pfWlanProbe((PVOID)func) != WLAN_STATUS_SUCCESS) { + //printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n"); + pfWlanRemove(); + ret = -1; + } + else { +#if CFG_DBG_GPIO_PINS + //printk(KERN_INFO "[%s] init debug gpio, 20100815 \n", __FUNCTION__); + /* Debug pins initialization */ + debug_gpio_init(); +#endif + } + +out: + //printk(KERN_INFO DRV_NAME"mtk_sdio_probe() done(%d)\n", ret); + return ret; +} +#endif + + +#if MTK_WCN_HIF_SDIO +static INT32 +mtk_sdio_remove(MTK_WCN_HIF_SDIO_CLTCTX cltCtx) +{ + INT32 ret = HIF_SDIO_ERR_SUCCESS; + //printk(KERN_INFO DRV_NAME"pfWlanRemove done\n"); + pfWlanRemove(); + + return ret; +} +#else +static void +mtk_sdio_remove ( + struct sdio_func *func + ) +{ + //printk(KERN_INFO DRV_NAME"mtk_sdio_remove()\n"); + +#if CFG_DBG_GPIO_PINS + //printk(KERN_INFO "[%s] deinit debug gpio \n", __FUNCTION__); + debug_gpio_deinit(); +#endif + + ASSERT(func); + //printk(KERN_INFO DRV_NAME"pfWlanRemove done\n"); + pfWlanRemove(); + + sdio_claim_host(func); + sdio_disable_func(func); + //printk(KERN_INFO DRV_NAME"sdio_disable_func() done\n"); + sdio_release_host(func); + + //printk(KERN_INFO DRV_NAME"mtk_sdio_remove() done\n"); +} +#endif + +#if (MTK_WCN_HIF_SDIO == 0) +static int +mtk_sdio_suspend ( + struct device * pDev, + pm_message_t state + ) +{ + //printk(KERN_INFO "mtk_sdio: mtk_sdio_suspend dev(0x%p)\n", pDev); + //printk(KERN_INFO "mtk_sdio: MediaTek SDIO WLAN driver\n"); + + return 0; +} + +int mtk_sdio_resume ( + struct device * pDev + ) +{ + //printk(KERN_INFO "mtk_sdio: mtk_sdio_resume dev(0x%p)\n", pDev); + + return 0; +} +#endif + + +/*----------------------------------------------------------------------------*/ +/*! +* \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 sdio bus +*/ +/*----------------------------------------------------------------------------*/ +WLAN_STATUS +glRegisterBus ( + probe_card pfProbe, + remove_card pfRemove + ) +{ + int ret = 0; + + ASSERT(pfProbe); + ASSERT(pfRemove); + + //printk(KERN_INFO "mtk_sdio: MediaTek SDIO WLAN driver\n"); + //printk(KERN_INFO "mtk_sdio: Copyright MediaTek Inc.\n"); + + pfWlanProbe = pfProbe; + pfWlanRemove = pfRemove; + +#if MTK_WCN_HIF_SDIO + /* register MTK sdio client */ + ret = ((mtk_wcn_hif_sdio_client_reg(&cltInfo) == HIF_SDIO_ERR_SUCCESS) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE); +#else + mtk_sdio_driver.probe = mtk_sdio_probe; + mtk_sdio_driver.remove = mtk_sdio_remove; + + mtk_sdio_driver.drv.suspend = mtk_sdio_suspend; + mtk_sdio_driver.drv.resume = mtk_sdio_resume; + + ret = (sdio_register_driver(&mtk_sdio_driver) == 0) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE; +#endif + + 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 MTK_WCN_HIF_SDIO + /* unregister MTK sdio client */ + mtk_wcn_hif_sdio_client_unreg(&cltInfo); +#else + sdio_unregister_driver(&mtk_sdio_driver); +#endif + + return; +} /* end of glUnregisterBus() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function stores hif related info, which is initialized before. +* +* \param[in] prGlueInfo Pointer to glue info structure +* \param[in] u4Cookie Pointer to UINT_32 memory base variable for _HIF_HPI +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +VOID +glSetHifInfo ( + P_GLUE_INFO_T prGlueInfo, + UINT_32 u4Cookie + ) +{ + P_GL_HIF_INFO_T prHif = NULL; + + prHif = &prGlueInfo->rHifInfo; + +#if MTK_WCN_HIF_SDIO + //prHif->prFuncInfo = ((MTK_WCN_HIF_SDIO_FUNCINFO *) u4Cookie); + prHif->prFuncInfo = prFunc; + prHif->cltCtx = *((MTK_WCN_HIF_SDIO_CLTCTX *) u4Cookie); + mtk_wcn_hif_sdio_set_drvdata(prHif->cltCtx, prGlueInfo); + +#else + prHif->func = (struct sdio_func *) u4Cookie; + + //printk(KERN_INFO DRV_NAME"prHif->func->dev = 0x%p\n", &prHif->func->dev); + //printk(KERN_INFO DRV_NAME"prHif->func->vendor = 0x%04X\n", prHif->func->vendor); + //printk(KERN_INFO DRV_NAME"prHif->func->device = 0x%04X\n", prHif->func->device); + //printk(KERN_INFO DRV_NAME"prHif->func->func = 0x%04X\n", prHif->func->num); + + sdio_set_drvdata(prHif->func, prGlueInfo); + + SET_NETDEV_DEV(prGlueInfo->prDevHandler, &prHif->func->dev); +#endif + + return; +} /* end of glSetHifInfo() */ + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function clears hif related info. +* +* \param[in] prGlueInfo Pointer to glue info structure +* +* \return (none) +*/ +/*----------------------------------------------------------------------------*/ +VOID +glClearHifInfo ( + P_GLUE_INFO_T prGlueInfo + ) +{ + //P_GL_HIF_INFO_T prHif = NULL; + //ASSERT(prGlueInfo); + //prHif = &prGlueInfo->rHifInfo; + + return; +} /* end of glClearHifInfo() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \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) +*/ +/*----------------------------------------------------------------------------*/ +BOOL +glBusInit ( + PVOID pvData + ) +{ +#if (MTK_WCN_HIF_SDIO == 0) + int ret = 0; + struct sdio_func *func = NULL; + + ASSERT(pvData); + + func = (struct sdio_func *) pvData; + + sdio_claim_host(func); + ret = sdio_set_block_size(func, 512); + sdio_release_host(func); + + if (ret) { + //printk(KERN_INFO DRV_NAME"sdio_set_block_size 512 failed!\n"); + } + else { + //printk(KERN_INFO DRV_NAME"sdio_set_block_size 512 done!\n"); + } + + //printk(KERN_INFO DRV_NAME"param: func->cur_blksize(%d)\n", func->cur_blksize); + //printk(KERN_INFO DRV_NAME"param: func->max_blksize(%d)\n", func->max_blksize); + //printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_size(%d)\n", func->card->host->max_blk_size); + //printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_count(%d)\n", func->card->host->max_blk_count); +#endif + 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 + ) +{ + + return; +} /* 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 +*/ +/*----------------------------------------------------------------------------*/ +INT_32 +glBusSetIrq ( + PVOID pvData, + PVOID pfnIsr, + PVOID pvCookie + ) +{ + int ret = 0; + +#if (MTK_WCN_HIF_SDIO == 0) + struct net_device *prNetDevice = NULL; + P_GLUE_INFO_T prGlueInfo = NULL; + P_GL_HIF_INFO_T prHifInfo = NULL; + + ASSERT(pvData); + if (!pvData) { + return -1; + } + prNetDevice = (struct net_device *) pvData; + + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prNetDevice); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + return -1; + } + + prHifInfo = &prGlueInfo->rHifInfo; + + sdio_claim_host(prHifInfo->func); + ret = sdio_claim_irq(prHifInfo->func, mtk_sdio_interrupt); + sdio_release_host(prHifInfo->func); +#endif + 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 + ) +{ +#if (MTK_WCN_HIF_SDIO == 0) + struct net_device *prNetDevice = NULL; + P_GLUE_INFO_T prGlueInfo = NULL; + P_GL_HIF_INFO_T prHifInfo = NULL; + int ret = 0; + + ASSERT(pvData); + if (!pvData) { + //printk(KERN_INFO DRV_NAME"%s null pvData\n", __FUNCTION__); + return; + } + prNetDevice = (struct net_device *) pvData; + + prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prNetDevice); + ASSERT(prGlueInfo); + if (!prGlueInfo) { + //printk(KERN_INFO DRV_NAME"%s no glue info\n", __FUNCTION__); + return; + } + + prHifInfo = &prGlueInfo->rHifInfo; + + sdio_claim_host(prHifInfo->func); + ret = sdio_release_irq(prHifInfo->func); + sdio_release_host(prHifInfo->func); +#endif + + return; +} /* end of glBusreeIrq() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Read a 32-bit device register +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] pu4Value Pointer to variable used to store read value +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +BOOL +kalDevRegRead ( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Register, + OUT PUINT_32 pu4Value + ) +{ + int ret = 0; + + ASSERT(prGlueInfo); + ASSERT(pu4Value); + +#if MTK_WCN_HIF_SDIO + ret = mtk_wcn_hif_sdio_readl(prGlueInfo->rHifInfo.cltCtx, u4Register, (PUINT32) pu4Value); +#else + if (!in_interrupt) { + sdio_claim_host(prGlueInfo->rHifInfo.func); + } + + *pu4Value = sdio_readl(prGlueInfo->rHifInfo.func, u4Register, &ret); + + if (!in_interrupt) { + sdio_release_host(prGlueInfo->rHifInfo.func); + } +#endif + + if (ret) { + DBGLOG(HAL, ERROR, ("sdio_readl() reports error: %x", ret)); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevRegRead() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write a 32-bit device register +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Register Register offset +* \param[in] u4Value Value to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +BOOL +kalDevRegWrite ( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Register, + IN UINT_32 u4Value + ) +{ + int ret = 0; + + ASSERT(prGlueInfo); + +#if MTK_WCN_HIF_SDIO + ret = mtk_wcn_hif_sdio_writel(prGlueInfo->rHifInfo.cltCtx, u4Register, u4Value); +#else + if (!in_interrupt) { + sdio_claim_host(prGlueInfo->rHifInfo.func); + } + + sdio_writel(prGlueInfo->rHifInfo.func, u4Value, u4Register, &ret); + + if (!in_interrupt) { + sdio_release_host(prGlueInfo->rHifInfo.func); + } +#endif + + if (ret) { + DBGLOG(HAL, ERROR, ("sdio_writel() reports error: %x", ret)); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevRegWrite() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Read device I/O port +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port I/O port offset +* \param[in] u2Len Length to be read +* \param[out] pucBuf Pointer to read buffer +* \param[in] u2ValidOutBufSize Length of the buffer valid to be accessed +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +BOOL +kalDevPortRead ( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_16 u2Port, + IN UINT_16 u2Len, + OUT PUINT_8 pucBuf, + IN UINT_16 u2ValidOutBufSize + ) +{ + P_GL_HIF_INFO_T prHifInfo = NULL; + PUINT_8 pucDst = NULL; + int count = u2Len; + int ret = 0; + int bNum = 0; + +#if (MTK_WCN_HIF_SDIO == 0) + struct sdio_func *prSdioFunc = NULL; +#endif + + #if DBG + //printk(KERN_INFO DRV_NAME"++kalDevPortRead++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u2Len); + #endif + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + ASSERT(pucBuf); + pucDst = pucBuf; + + ASSERT(u2Len <= u2ValidOutBufSize); + +#if (MTK_WCN_HIF_SDIO == 0) + prSdioFunc = prHifInfo->func; + + ASSERT(prSdioFunc->cur_blksize > 0); + + if (!in_interrupt) { + sdio_claim_host(prSdioFunc); + } + + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= prSdioFunc->cur_blksize) { + count -= prSdioFunc->cur_blksize; + bNum++; + } + if (count > 0 && bNum > 0) { + bNum++; + } + + if (bNum > 0) { + ret = sdio_readsb(prSdioFunc, pucDst, u2Port, prSdioFunc->cur_blksize * bNum); + +#ifdef CONFIG_X86 + /* ENE workaround */ + { + int tmp; + sdio_writel(prSdioFunc, 0x0, SDIO_X86_WORKAROUND_WRITE_MCR, &tmp); + } +#endif + + } + else { + ret = sdio_readsb(prSdioFunc, pucDst, u2Port, count); + } + + if (!in_interrupt) { + sdio_release_host(prSdioFunc); + } +#else + + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= (prGlueInfo->rHifInfo).prFuncInfo->blk_sz) { + count -= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz); + bNum++; + } + if (count > 0 && bNum > 0) { + bNum++; + } + + if (bNum > 0) { + ret = mtk_wcn_hif_sdio_read_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucDst, + ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz) * bNum); + } + else { + ret = mtk_wcn_hif_sdio_read_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucDst, count); + } +#endif + + if (ret) { + DBGLOG(HAL, ERROR, ("sdio_readsb() reports error: %x", ret)); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevPortRead() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write device I/O port +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u2Port I/O port offset +* \param[in] u2Len Length to be write +* \param[in] pucBuf Pointer to write buffer +* \param[in] u2ValidInBufSize Length of the buffer valid to be accessed +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +BOOL +kalDevPortWrite ( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_16 u2Port, + IN UINT_16 u2Len, + IN PUINT_8 pucBuf, + IN UINT_16 u2ValidInBufSize + ) +{ + P_GL_HIF_INFO_T prHifInfo = NULL; + PUINT_8 pucSrc = NULL; + int count = u2Len; + int ret = 0; + int bNum = 0; + +#if (MTK_WCN_HIF_SDIO == 0) + struct sdio_func *prSdioFunc = NULL; +#endif + + #if DBG + //printk(KERN_INFO DRV_NAME"++kalDevPortWrite++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u2Len); + #endif + + ASSERT(prGlueInfo); + prHifInfo = &prGlueInfo->rHifInfo; + + ASSERT(pucBuf); + pucSrc = pucBuf; + + ASSERT(u2Len <= u2ValidInBufSize); + +#if (MTK_WCN_HIF_SDIO == 0) + prSdioFunc = prHifInfo->func; + ASSERT(prSdioFunc->cur_blksize > 0); + + if (!in_interrupt) { + sdio_claim_host(prSdioFunc); + } + + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= prSdioFunc->cur_blksize) { + count -= prSdioFunc->cur_blksize; + bNum++; + } + if (count > 0 && bNum > 0) { + bNum++; + } + + if (bNum > 0) { // block mode + ret = sdio_writesb(prSdioFunc, u2Port, pucSrc, prSdioFunc->cur_blksize * bNum); + +#ifdef CONFIG_X86 + /* ENE workaround */ + { + int tmp; + sdio_writel(prSdioFunc, 0x0, SDIO_X86_WORKAROUND_WRITE_MCR, &tmp); + } +#endif + + } + else { // byte mode + + ret = sdio_writesb(prSdioFunc, u2Port, pucSrc, count); + } + + if (!in_interrupt) { + sdio_release_host(prSdioFunc); + } +#else + /* Split buffer into multiple single block to workaround hifsys */ + while (count >= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz)) { + count -= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz); + bNum++; + } + if (count > 0 && bNum > 0) { + bNum++; + } + + if (bNum > 0) { // block mode + ret = mtk_wcn_hif_sdio_write_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucSrc, + ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz) * bNum); + } + else { // byte mode + ret = mtk_wcn_hif_sdio_write_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucSrc, count); + } +#endif + + if (ret) { + DBGLOG(HAL, ERROR, ("sdio_writesb() reports error: %x", ret)); + } + + return (ret) ? FALSE : TRUE; +} /* end of kalDevPortWrite() */ + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief Write device I/O port in byte with CMD52 +* +* \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. +* \param[in] u4Addr I/O port offset +* \param[in] ucData Single byte of data to be written +* +* \retval TRUE operation success +* \retval FALSE operation fail +*/ +/*----------------------------------------------------------------------------*/ +BOOL +kalDevWriteWithSdioCmd52 ( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Addr, + IN UINT_8 ucData + ) +{ + int ret = 0; + +#if (MTK_WCN_HIF_SDIO == 0) + if (!in_interrupt) { + sdio_claim_host(prGlueInfo->rHifInfo.func); + } + + sdio_writeb(prGlueInfo->rHifInfo.func, ucData, u4Addr, &ret); + + if (!in_interrupt) { + sdio_release_host(prGlueInfo->rHifInfo.func); + } +#else + ret = mtk_wcn_hif_sdio_writeb(prGlueInfo->rHifInfo.cltCtx, u4Addr, ucData); +#endif + + if (ret) { + DBGLOG(HAL, ERROR, ("sdio_writeb() reports error: %x", ret)); + } + + return (ret) ? FALSE : TRUE; + +} /* end of kalDevWriteWithSdioCmd52() */ + + +VOID +glSetPowerState ( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 ePowerMode + ) +{ + return; +} + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/x86.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/x86.c new file mode 100755 index 000000000000..eef362e4ffc3 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/hif/sdio/x86.c @@ -0,0 +1,68 @@ +/****************************************************************************** +*[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. +******************************************************************************/ + + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: mt6516-evb.c $ + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_kal.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_kal.h new file mode 100755 index 000000000000..87360fb842b6 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_kal.h @@ -0,0 +1,1988 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_kal.h $ + * + * 02 06 2012 wh.su + * [ALPS00109161] [Need Patch] [Volunteer Patch] [Wi-Fi] Support the set tx power driver cmd + * Adding the AP mode channel query filter. + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 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 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 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 cm.chang + * NULL + * Add RLM and CNM debug message for XLOG + * + * 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 04 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 Xlog 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 + * Add XLOG related code and define. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 similiar 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 continous memory demands + * separate kalMemAlloc() into virtually-continous and physically-continous 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 availble 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" + + +#if CFG_ENABLE_BT_OVER_WIFI + #include "nic/bow.h" +#endif + +#if DBG +extern int allocatedMemSize; +#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_NUM +} ENUM_SPIN_LOCK_CATEGORY_E; + +/* event for assoc infomation 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 continous */ + 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 + +/******************************************************************************* +* P U B 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 Driver Layer */ +/*----------------------------------------------------------------------------*/ +#define KAL_SPIN_LOCK_DECLARATION() UINT_32 __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) + +#define kalUpdateReAssocRspInfo(prGlueInfo, pucFrameBody, u4FrameBodyLen) + +/*----------------------------------------------------------------------------*/ +/* 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; \ + printk(KERN_INFO DRV_NAME "0x%p(%ld) allocated (%s:%s)\n", \ + pvAddr, (UINT_32)u4Size, __FILE__, __FUNCTION__); \ + } \ + 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; \ + printk(KERN_INFO DRV_NAME "0x%p(%ld) freed (%s:%s)\n", \ + pvAddr, (UINT_32)u4Size, __FILE__, __FUNCTION__); \ + } \ + 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) + +/* 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) \ + {struct sk_buff *skb = (struct sk_buff *)pvPacket; \ + memcpy(pucDestBuffer, skb->data, skb->len);} + +#define kalGetTimeTick() jiffies_to_msecs(jiffies) + +#define kalPrint printk + +#if CFG_SUPPORT_XLOG +#define XLOG_TAG "wlan" + +#define XLOG_FUNC(__LEVEL, __FMT...)\ + if (__LEVEL == ANDROID_LOG_ERROR) {\ + xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, ##__FMT);\ + } \ + else if (__LEVEL == ANDROID_LOG_WARN) {\ + xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, ##__FMT);\ + } \ + else if (__LEVEL == ANDROID_LOG_INFO) {\ + xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, ##__FMT);\ + } \ + else if (__LEVEL == ANDROID_LOG_DEBUG) {\ + xlog_printk(ANDROID_LOG_DEBUG, XLOG_TAG, ##__FMT);\ + } \ + else if (__LEVEL == ANDROID_LOG_VERBOSE) {\ + xlog_printk(ANDROID_LOG_VERBOSE, XLOG_TAG, ##__FMT);\ + } + +#define AIS_ERROR_LOGFUNC(_Fmt...) +#define AIS_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define AIS_INFO_LOGFUNC(_Fmt...) +#define AIS_STATE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define AIS_EVENT_LOGFUNC(_Fmt...) +#define AIS_TRACE_LOGFUNC(_Fmt...) +#define AIS_LOUD_LOGFUNC(_Fmt...) +#define AIS_TEMP_LOGFUNC(_Fmt...) + +#define AIS_ERROR_LOGDUMP8(x, y) +#define AIS_WARN_LOGDUMP8(x, y) +#define AIS_INFO_LOGDUMP8(x, y) +#define AIS_STATE_LOGDUMP8(x, y) +#define AIS_EVENT_LOGDUMP8(x, y) +#define AIS_TRACE_LOGDUMP8(x, y) +#define AIS_LOUD_LOGDUMP8(x, y) +#define AIS_TEMP_LOGDUMP8(x, y) + +#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 INTR_ERROR_LOGDUMP8(x, y) +#define INTR_WARN_LOGDUMP8(x, y) +#define INTR_INFO_LOGDUMP8(x, y) +#define INTR_STATE_LOGDUMP8(x, y) +#define INTR_EVENT_LOGDUMP8(x, y) +#define INTR_TRACE_LOGDUMP8(x, y) +#define INTR_LOUD_LOGDUMP8(x, y) +#define INTR_TEMP_LOGDUMP8(x, y) + +#define INIT_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define INIT_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define INIT_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define INIT_STATE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define INIT_EVENT_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define INIT_TRACE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_DEBUG, XLOG_TAG, _Fmt) +#define INIT_LOUD_LOGFUNC(_Fmt...) +#define INIT_TEMP_LOGFUNC(_Fmt...) + +#define INIT_ERROR_LOGDUMP8(x, y) +#define INIT_WARN_LOGDUMP8(x, y) +#define INIT_INFO_LOGDUMP8(x, y) +#define INIT_STATE_LOGDUMP8(x, y) +#define INIT_EVENT_LOGDUMP8(x, y) +#define INIT_TRACE_LOGDUMP8(x, y) +#define INIT_LOUD_LOGDUMP8(x, y) +#define INIT_TEMP_LOGDUMP8(x, y) + +#define AAA_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define AAA_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define AAA_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define AAA_STATE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define AAA_EVENT_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define AAA_TRACE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_DEBUG, XLOG_TAG, _Fmt) +#define AAA_LOUD_LOGFUNC(_Fmt...) +#define AAA_TEMP_LOGFUNC(_Fmt...) + +#define AAA_ERROR_LOGDUMP8(x, y) +#define AAA_WARN_LOGDUMP8(x, y) +#define AAA_INFO_LOGDUMP8(x, y) +#define AAA_STATE_LOGDUMP8(x, y) +#define AAA_EVENT_LOGDUMP8(x, y) +#define AAA_TRACE_LOGDUMP8(x, y) +#define AAA_LOUD_LOGDUMP8(x, y) +#define AAA_TEMP_LOGDUMP8(x, y) + +#define ROAMING_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define ROAMING_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define ROAMING_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define ROAMING_STATE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define ROAMING_EVENT_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define ROAMING_TRACE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_DEBUG, XLOG_TAG, _Fmt) +#define ROAMING_LOUD_LOGFUNC(_Fmt...) +#define ROAMING_TEMP_LOGFUNC(_Fmt...) + +#define ROAMING_ERROR_LOGDUMP8(x, y) +#define ROAMING_WARN_LOGDUMP8(x, y) +#define ROAMING_INFO_LOGDUMP8(x, y) +#define ROAMING_STATE_LOGDUMP8(x, y) +#define ROAMING_EVENT_LOGDUMP8(x, y) +#define ROAMING_TRACE_LOGDUMP8(x, y) +#define ROAMING_LOUD_LOGDUMP8(x, y) +#define ROAMING_TEMP_LOGDUMP8(x, y) + +#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 REQ_ERROR_LOGDUMP8(x, y) +#define REQ_WARN_LOGDUMP8(x, y) +#define REQ_INFO_LOGDUMP8(x, y) +#define REQ_STATE_LOGDUMP8(x, y) +#define REQ_EVENT_LOGDUMP8(x, y) +#define REQ_TRACE_LOGDUMP8(x, y) +#define REQ_LOUD_LOGDUMP8(x, y) +#define REQ_TEMP_LOGDUMP8(x, y) + +#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...) +#define TX_LOUD_LOGFUNC(_Fmt...) +#define TX_TEMP_LOGFUNC(_Fmt...) + +#define TX_ERROR_LOGDUMP8(x, y) +#define TX_WARN_LOGDUMP8(x, y) +#define TX_INFO_LOGDUMP8(x, y) +#define TX_STATE_LOGDUMP8(x, y) +#define TX_EVENT_LOGDUMP8(x, y) +#define TX_TRACE_LOGDUMP8(x, y) +#define TX_LOUD_LOGDUMP8(x, y) +#define TX_TEMP_LOGDUMP8(x, y) + +#define RX_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define RX_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _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 RX_ERROR_LOGDUMP8(x, y) +#define RX_WARN_LOGDUMP8(x, y) +#define RX_INFO_LOGDUMP8(x, y) +#define RX_STATE_LOGDUMP8(x, y) +#define RX_EVENT_LOGDUMP8(x, y) +#define RX_TRACE_LOGDUMP8(x, y) +#define RX_LOUD_LOGDUMP8(x, y) +#define RX_TEMP_LOGDUMP8(x, y) + +#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 RFTEST_ERROR_LOGDUMP8(x, y) +#define RFTEST_WARN_LOGDUMP8(x, y) +#define RFTEST_INFO_LOGDUMP8(x, y) +#define RFTEST_STATE_LOGDUMP8(x, y) +#define RFTEST_EVENT_LOGDUMP8(x, y) +#define RFTEST_TRACE_LOGDUMP8(x, y) +#define RFTEST_LOUD_LOGDUMP8(x, y) +#define RFTEST_TEMP_LOGDUMP8(x, y) + +#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 EMU_ERROR_LOGDUMP8(x, y) +#define EMU_WARN_LOGDUMP8(x, y) +#define EMU_INFO_LOGDUMP8(x, y) +#define EMU_STATE_LOGDUMP8(x, y) +#define EMU_EVENT_LOGDUMP8(x, y) +#define EMU_TRACE_LOGDUMP8(x, y) +#define EMU_LOUD_LOGDUMP8(x, y) +#define EMU_TEMP_LOGDUMP8(x, y) + +#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 HEM_ERROR_LOGDUMP8(x, y) +#define HEM_WARN_LOGDUMP8(x, y) +#define HEM_INFO_LOGDUMP8(x, y) +#define HEM_STATE_LOGDUMP8(x, y) +#define HEM_EVENT_LOGDUMP8(x, y) +#define HEM_TRACE_LOGDUMP8(x, y) +#define HEM_LOUD_LOGDUMP8(x, y) +#define HEM_TEMP_LOGDUMP8(x, y) + +#define RLM_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define RLM_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define RLM_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _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 RLM_ERROR_LOGDUMP8(x, y) +#define RLM_WARN_LOGDUMP8(x, y) +#define RLM_INFO_LOGDUMP8(x, y) +#define RLM_STATE_LOGDUMP8(x, y) +#define RLM_EVENT_LOGDUMP8(x, y) +#define RLM_TRACE_LOGDUMP8(x, y) +#define RLM_LOUD_LOGDUMP8(x, y) +#define RLM_TEMP_LOGDUMP8(x, y) + +#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 MEM_ERROR_LOGDUMP8(x, y) +#define MEM_WARN_LOGDUMP8(x, y) +#define MEM_INFO_LOGDUMP8(x, y) +#define MEM_STATE_LOGDUMP8(x, y) +#define MEM_EVENT_LOGDUMP8(x, y) +#define MEM_TRACE_LOGDUMP8(x, y) +#define MEM_LOUD_LOGDUMP8(x, y) +#define MEM_TEMP_LOGDUMP8(x, y) + +#define CNM_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define CNM_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define CNM_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _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 CNM_ERROR_LOGDUMP8(x, y) +#define CNM_WARN_LOGDUMP8(x, y) +#define CNM_INFO_LOGDUMP8(x, y) +#define CNM_STATE_LOGDUMP8(x, y) +#define CNM_EVENT_LOGDUMP8(x, y) +#define CNM_TRACE_LOGDUMP8(x, y) +#define CNM_LOUD_LOGDUMP8(x, y) +#define CNM_TEMP_LOGDUMP8(x, y) + +#define RSN_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define RSN_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define RSN_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define RSN_STATE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define RSN_EVENT_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define RSN_TRACE_LOGFUNC(_Fmt...) +#define RSN_LOUD_LOGFUNC(_Fmt...) +#define RSN_TEMP_LOGFUNC(_Fmt...) + +#define RSN_ERROR_LOGDUMP8(x, y) +#define RSN_WARN_LOGDUMP8(x, y) +#define RSN_INFO_LOGDUMP8(x, y) +#define RSN_STATE_LOGDUMP8(x, y) +#define RSN_EVENT_LOGDUMP8(x, y) +#define RSN_TRACE_LOGDUMP8(x, y) +#define RSN_LOUD_LOGDUMP8(x, y) +#define RSN_TEMP_LOGDUMP8(x, y) + +#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 BSS_ERROR_LOGDUMP8(x, y) +#define BSS_WARN_LOGDUMP8(x, y) +#define BSS_INFO_LOGDUMP8(x, y) +#define BSS_STATE_LOGDUMP8(x, y) +#define BSS_EVENT_LOGDUMP8(x, y) +#define BSS_TRACE_LOGDUMP8(x, y) +#define BSS_LOUD_LOGDUMP8(x, y) +#define BSS_TEMP_LOGDUMP8(x, y) + +#define SCN_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define SCN_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _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 SCN_ERROR_LOGDUMP8(x, y) +#define SCN_WARN_LOGDUMP8(x, y) +#define SCN_INFO_LOGDUMP8(x, y) +#define SCN_STATE_LOGDUMP8(x, y) +#define SCN_EVENT_LOGDUMP8(x, y) +#define SCN_TRACE_LOGDUMP8(x, y) +#define SCN_LOUD_LOGDUMP8(x, y) +#define SCN_TEMP_LOGDUMP8(x, y) + +#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 SAA_ERROR_LOGDUMP8(x, y) +#define SAA_WARN_LOGDUMP8(x, y) +#define SAA_INFO_LOGDUMP8(x, y) +#define SAA_STATE_LOGDUMP8(x, y) +#define SAA_EVENT_LOGDUMP8(x, y) +#define SAA_TRACE_LOGDUMP8(x, y) +#define SAA_LOUD_LOGDUMP8(x, y) +#define SAA_TEMP_LOGDUMP8(x, y) + +#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 P2P_ERROR_LOGDUMP8(x, y) +#define P2P_WARN_LOGDUMP8(x, y) +#define P2P_INFO_LOGDUMP8(x, y) +#define P2P_STATE_LOGDUMP8(x, y) +#define P2P_EVENT_LOGDUMP8(x, y) +#define P2P_TRACE_LOGDUMP8(x, y) +#define P2P_LOUD_LOGDUMP8(x, y) +#define P2P_TEMP_LOGDUMP8(x, y) + +#define QM_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _Fmt) +#define QM_WARN_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_WARN, XLOG_TAG, _Fmt) +#define QM_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _Fmt) +#define QM_STATE_LOGFUNC(_Fmt...) +#define QM_EVENT_LOGFUNC(_Fmt...) +#define QM_TRACE_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_DEBUG, XLOG_TAG, _Fmt) +#define QM_LOUD_LOGFUNC(_Fmt...) +#define QM_TEMP_LOGFUNC(_Fmt...) + +#define QM_ERROR_LOGDUMP8(x, y) +#define QM_WARN_LOGDUMP8(x, y) +#define QM_INFO_LOGDUMP8(x, y) +#define QM_STATE_LOGDUMP8(x, y) +#define QM_EVENT_LOGDUMP8(x, y) +#define QM_TRACE_LOGDUMP8(x, y) +#define QM_LOUD_LOGDUMP8(x, y) +#define QM_TEMP_LOGDUMP8(x, y) + +#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 SEC_ERROR_LOGDUMP8(x, y) +#define SEC_WARN_LOGDUMP8(x, y) +#define SEC_INFO_LOGDUMP8(x, y) +#define SEC_STATE_LOGDUMP8(x, y) +#define SEC_EVENT_LOGDUMP8(x, y) +#define SEC_TRACE_LOGDUMP8(x, y) +#define SEC_LOUD_LOGDUMP8(x, y) +#define SEC_TEMP_LOGDUMP8(x, y) + +#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 BOW_ERROR_LOGDUMP8(x, y) +#define BOW_WARN_LOGDUMP8(x, y) +#define BOW_INFO_LOGDUMP8(x, y) +#define BOW_STATE_LOGDUMP8(x, y) +#define BOW_EVENT_LOGDUMP8(x, y) +#define BOW_TRACE_LOGDUMP8(x, y) +#define BOW_LOUD_LOGDUMP8(x, y) +#define BOW_TEMP_LOGDUMP8(x, y) + +#define HAL_ERROR_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_ERROR, XLOG_TAG, _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 HAL_ERROR_LOGDUMP8(x, y) +#define HAL_WARN_LOGDUMP8(x, y) +#define HAL_INFO_LOGDUMP8(x, y) +#define HAL_STATE_LOGDUMP8(x, y) +#define HAL_EVENT_LOGDUMP8(x, y) +#define HAL_TRACE_LOGDUMP8(x, y) +#define HAL_LOUD_LOGDUMP8(x, y) +#define HAL_TEMP_LOGDUMP8(x, y) + +#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 WAPI_ERROR_LOGDUMP8(x, y) +#define WAPI_WARN_LOGDUMP8(x, y) +#define WAPI_INFO_LOGDUMP8(x, y) +#define WAPI_STATE_LOGDUMP8(x, y) +#define WAPI_EVENT_LOGDUMP8(x, y) +#define WAPI_TRACE_LOGDUMP8(x, y) +#define WAPI_LOUD_LOGDUMP8(x, y) +#define WAPI_TEMP_LOGDUMP8(x, y) + +#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 SW1_ERROR_LOGDUMP8(x, y) +#define SW1_WARN_LOGDUMP8(x, y) +#define SW1_INFO_LOGDUMP8(x, y) +#define SW1_STATE_LOGDUMP8(x, y) +#define SW1_EVENT_LOGDUMP8(x, y) +#define SW1_TRACE_LOGDUMP8(x, y) +#define SW1_LOUD_LOGDUMP8(x, y) +#define SW1_TEMP_LOGDUMP8(x, y) + +#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 SW2_ERROR_LOGDUMP8(x, y) +#define SW2_WARN_LOGDUMP8(x, y) +#define SW2_INFO_LOGDUMP8(x, y) +#define SW2_STATE_LOGDUMP8(x, y) +#define SW2_EVENT_LOGDUMP8(x, y) +#define SW2_TRACE_LOGDUMP8(x, y) +#define SW2_LOUD_LOGDUMP8(x, y) +#define SW2_TEMP_LOGDUMP8(x, y) + +#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 SW3_ERROR_LOGDUMP8(x, y) +#define SW3_WARN_LOGDUMP8(x, y) +#define SW3_INFO_LOGDUMP8(x, y) +#define SW3_STATE_LOGDUMP8(x, y) +#define SW3_EVENT_LOGDUMP8(x, y) +#define SW3_TRACE_LOGDUMP8(x, y) +#define SW3_LOUD_LOGDUMP8(x, y) +#define SW3_TEMP_LOGDUMP8(x, y) + +#define SW4_ERROR_LOGFUNC(_Fmt...) +#define SW4_WARN_LOGFUNC(_Fmt...) +#define SW4_INFO_LOGFUNC(_Fmt...) xlog_printk(ANDROID_LOG_INFO, XLOG_TAG, _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...) + +#define SW4_ERROR_LOGDUMP8(x, y) +#define SW4_WARN_LOGDUMP8(x, y) +#define SW4_INFO_LOGDUMP8(x, y) +#define SW4_STATE_LOGDUMP8(x, y) +#define SW4_EVENT_LOGDUMP8(x, y) +#define SW4_TRACE_LOGDUMP8(x, y) dumpMemory8(ANDROID_LOG_DEBUG, x, y) +#define SW4_LOUD_LOGDUMP8(x, y) +#define SW4_TEMP_LOGDUMP8(x, y) + +#endif + +#define kalBreakPoint() \ + do { \ + BUG(); \ + panic("Oops"); \ + } while(0) + +#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) + +/******************************************************************************* +* 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 PUINT_32 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 + ); + +BOOL +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 + ); + +#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 + ); + + +/*----------------------------------------------------------------------------*/ +/* Routines in interface - ehpi/sdio.c */ +/*----------------------------------------------------------------------------*/ +BOOL +kalDevRegRead( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Register, + OUT PUINT_32 pu4Value + ); + +BOOL +kalDevRegWrite( + P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Register, + IN UINT_32 u4Value + ); + +BOOL +kalDevPortRead( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_16 u2Port, + IN UINT_16 u2Len, + OUT PUINT_8 pucBuf, + IN UINT_16 u2ValidOutBufSize + ); + +BOOL +kalDevPortWrite( + P_GLUE_INFO_T prGlueInfo, + IN UINT_16 u2Port, + IN UINT_16 u2Len, + IN PUINT_8 pucBuf, + IN UINT_16 u2ValidInBufSize + ); + +BOOL +kalDevWriteWithSdioCmd52 ( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Addr, + IN UINT_8 ucData + ); + + + #if CFG_SUPPORT_EXT_CONFIG +UINT_32 +kalReadExtCfg ( + IN P_GLUE_INFO_T prGlueInfo + ); + #endif + +BOOL +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 +); + +inline 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 BOOL fgRead, + IN BOOL fgWaitResp, + IN BOOL fgCmd, + IN BOOL 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 (unsigned long arg); + +VOID +kalSetEvent (P_GLUE_INFO_T pr); + + +/*----------------------------------------------------------------------------*/ +/* NVRAM/Registry Service */ +/*----------------------------------------------------------------------------*/ +BOOLEAN +kalIsConfigurationExist( + IN P_GLUE_INFO_T prGlueInfo + ); + +P_REG_INFO_T +kalGetConfiguration( + IN P_GLUE_INFO_T prGlueInfo + ); + +VOID +kalGetConfigurationVersion( + IN P_GLUE_INFO_T prGlueInfo, + OUT PUINT_16 pu2Part1CfgOwnVersion, + OUT PUINT_16 pu2Part1CfgPeerVersion, + OUT PUINT_16 pu2Part2CfgOwnVersion, + OUT PUINT_16 pu2Part2CfgPeerVersion + ); + +BOOLEAN +kalCfgDataRead16( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Offset, + OUT PUINT_16 pu2Data + ); + +BOOLEAN +kalCfgDataWrite16( + IN P_GLUE_INFO_T prGlueInfo, + IN UINT_32 u4Offset, + IN UINT_16 u2Data + ); + +/*----------------------------------------------------------------------------*/ +/* WSC Connection */ +/*----------------------------------------------------------------------------*/ +BOOLEAN +kalWSCGetActiveState( + IN P_GLUE_INFO_T prGlueInfo + ); + +/*----------------------------------------------------------------------------*/ +/* RSSI Updating */ +/*----------------------------------------------------------------------------*/ +VOID +kalUpdateRSSI( + IN P_GLUE_INFO_T prGlueInfo, + IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx, + IN INT_8 cRssi, + IN INT_8 cLinkQuality + ); + + +/*----------------------------------------------------------------------------*/ +/* I/O Buffer Pre-allocation */ +/*----------------------------------------------------------------------------*/ +BOOLEAN +kalInitIOBuffer( + VOID + ); + +VOID +kalUninitIOBuffer( + VOID + ); + +PVOID +kalAllocateIOBuffer( + IN UINT_32 u4AllocSize + ); + +VOID +kalReleaseIOBuffer( + IN PVOID pvAddr, + IN UINT_32 u4Size + ); + +VOID +kalGetChannelList( + IN P_GLUE_INFO_T prGlueInfo, + IN ENUM_BAND_T eSpecificBand, + IN UINT_8 ucMaxChannelNum, + IN PUINT_8 pucNumOfChannel, + IN P_RF_CHANNEL_INFO_T paucChannelList + ); + +BOOL +kalIsAPmode( + IN P_GLUE_INFO_T prGlueInfo + ); + +#if CFG_SUPPORT_802_11W +/*----------------------------------------------------------------------------*/ +/* 802.11W */ +/*----------------------------------------------------------------------------*/ +UINT_32 +kalGetMfpSetting( + IN P_GLUE_INFO_T prGlueInfo + ); +#endif + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +int tx_thread(void *data); + +#endif /* _GL_KAL_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_os.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_os.h new file mode 100755 index 000000000000..4f6272c35a30 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_os.h @@ -0,0 +1,1093 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_os.h $ + * + * 01 09 2012 terry.wu + * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork + * cfg80211 integration for p2p network. + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 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 19 2011 yuche.tsai + * NULL + * Fix type conflict. + * + * 11 19 2011 yuche.tsai + * NULL + * Add P2P RSSI Link Quality Query Support. (Default Off) + * + * 11 16 2011 yuche.tsai + * NULL + * Avoid using work thread. + * + * 11 11 2011 yuche.tsai + * NULL + * Fix work thread cancel issue. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 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 cp.wu + * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events + * sync. whole-chip resetting mechanism to V2.0 branch. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 64 /* packets */ +#define CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD 32 /* 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 IPVERSION 4 +#define IP_HEADER_LEN 20 + +#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 DRV_NAME "[MT6620]: " +#elif defined(MT5931) + #define DRV_NAME "[MT5931]: " +#elif defined(MT6628) + #define DRV_NAME "[MT6628]: " +#endif + +/* Define if target platform is Android. + * It should already be defined in Android kernel source + */ +#ifndef CONFIG_ANDROID +#define CONFIG_ANDROID 0 +#endif + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include /* constant of kernel version */ + +#include /* bitops.h */ + +#include /* struct timer_list */ +#include /* jiffies */ +#include /* udelay and mdelay macro */ + +#if CONFIG_ANDROID +#include +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12) +#include /* IRQT_FALLING */ +#endif + +#include /* struct net_device, struct net_device_stats */ +#include /* for eth_type_trans() function */ +#include /* struct iw_statistics */ +#include +#include /* struct in_device */ + +#include /* struct iphdr */ + +#include /* for memcpy()/memset() function */ +#include /* for offsetof() macro */ + +#include /* The proc filesystem constants/structures */ + +#include /* for rtnl_lock() and rtnl_unlock() */ +#include /* kthread_should_stop(), kthread_run() */ +#include /* for copy_from_user() */ +#include /* for firmware download */ +#include + +#include /* for kfifo interface */ +#include /* for cdev interface */ + +#include /* for firmware download */ + +#if defined(_HIF_SDIO) +#include +#include +#endif + +#include + + +#include /* readw and writew */ + +#if WIRELESS_EXT > 12 +#include +#endif + +#include "version.h" +#include "config.h" + +#if CFG_ENABLE_WIFI_DIRECT_CFG_80211 +#include +#include +#endif + +#include "gl_typedef.h" +#include "typedef.h" +#include "queue.h" +#include "gl_kal.h" +#if CFG_CHIP_RESET_SUPPORT + #include "gl_rst.h" +#endif +#include "hif.h" + + +#include "debug.h" + +#include "wlan_lib.h" +#include "wlan_oid.h" + + +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_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_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; +#endif + +typedef struct _GL_IO_REQ_T { + QUE_ENTRY_T rQueEntry; + //wait_queue_head_t cmdwait_q; + BOOL fgRead; + BOOL fgWaitResp; +#if CFG_ENABLE_WIFI_DIRECT + BOOL 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 + +/* +* 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_32 u4Flag; /* GLUE_FLAG_XXX */ + UINT_32 u4PendFlag; + //UINT_32 u4TimeoutFlag; + UINT_32 u4ReadyFlag; /* check if card is ready */ + + /* 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; + + /* NVRAM availability */ + BOOLEAN fgNvramAvailable; + + BOOLEAN fgMcrAccessAllowed; + + /* MAC Address Overriden by IOCTL */ + BOOLEAN fgIsMacAddrOverride; + PARAM_MAC_ADDRESS rMacAddrOverride; + + SET_TXPWR_CTRL_T rTxPwr; +}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + /* linux 2.4 */ + typedef void (*PFN_WLANISR)(int irq, void *dev_id, struct pt_regs *regs); +#else + typedef irqreturn_t (*PFN_WLANISR)(int irq, void *dev_id, struct pt_regs *regs); +#endif + +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 + + +/******************************************************************************* +* P U B 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])); \ + } +#else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ + #define GLUE_SPIN_LOCK_DECLARATION() UINT_32 __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); \ + } +#endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */ + + +/*----------------------------------------------------------------------------*/ +/* Macros for accessing Reserved Fields of native packet */ +/*----------------------------------------------------------------------------*/ +#define GLUE_GET_PKT_QUEUE_ENTRY(_p) \ + (&( ((struct sk_buff *)(_p))->cb[0] )) + +#define GLUE_GET_PKT_DESCRIPTOR(_prQueueEntry) \ + ((P_NATIVE_PACKET) ((UINT_32)_prQueueEntry - offsetof(struct sk_buff, cb[0])) ) + +#define GLUE_SET_PKT_FLAG_802_11(_p) \ + (*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) |= BIT(7)) + +#define GLUE_SET_PKT_FLAG_1X(_p) \ + (*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) |= BIT(6)) + +#define GLUE_SET_PKT_FLAG_PAL(_p) \ + (*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) |= BIT(5)) + +#define GLUE_SET_PKT_FLAG_P2P(_p) \ + (*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) |= BIT(4)) + + + +#define GLUE_SET_PKT_TID(_p, _tid) \ + (*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) |= (((UINT_8)((_tid) & (BITS(0,3)))))) + + +#define GLUE_SET_PKT_FRAME_LEN(_p, _u2PayloadLen) \ + (*((PUINT_16) &( ((struct sk_buff *)(_p))->cb[6] )) = (UINT_16)(_u2PayloadLen)) + +#define GLUE_GET_PKT_FRAME_LEN(_p) \ + (*((PUINT_16) &( ((struct sk_buff *)(_p))->cb[6] )) ) + + +#define GLUE_GET_PKT_IS_802_11(_p) \ + ((*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) ) & (BIT(7))) + +#define GLUE_GET_PKT_IS_1X(_p) \ + ((*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) ) & (BIT(6))) + +#define GLUE_GET_PKT_TID(_p) \ + ((*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) ) & (BITS(0,3))) + + +#define GLUE_GET_PKT_IS_PAL(_p) \ + ((*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) ) & (BIT(5))) + +#define GLUE_GET_PKT_IS_P2P(_p) \ + ((*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[4] )) ) & (BIT(4))) + + +#define GLUE_SET_PKT_HEADER_LEN(_p, _ucMacHeaderLen) \ + (*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[5] )) = (UINT_8)(_ucMacHeaderLen)) + +#define GLUE_GET_PKT_HEADER_LEN(_p) \ + (*((PUINT_8) &( ((struct sk_buff *)(_p))->cb[5] )) ) + +#define GLUE_SET_PKT_ARRIVAL_TIME(_p, _rSysTime) \ + (*((POS_SYSTIME) &( ((struct sk_buff *)(_p))->cb[8] )) = (OS_SYSTIME)(_rSysTime)) + +#define GLUE_GET_PKT_ARRIVAL_TIME(_p) \ + (*((POS_SYSTIME) &( ((struct sk_buff *)(_p))->cb[8] )) ) + +/* Check validity of prDev, private data, and pointers */ +#define GLUE_CHK_DEV(prDev) \ + ((prDev && 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 ( + struct net_device *prDev, + char *pucDevName + ); + +INT_32 +procInitProcfs ( + struct net_device *prDev, + char *pucDevName + ); +#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 +p2pSetMulticastListWorkQueueWrapper( + P_GLUE_INFO_T prGlueInfo + ); + + + +#endif + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _GL_OS_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_rst.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_rst.h new file mode 100755 index 000000000000..be2c30913096 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_rst.h @@ -0,0 +1,171 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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 +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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 +******************************************************************************** +*/ +/* 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; + +typedef enum _ENUM_WMTRSTMSG_TYPE_T{ + WMTRSTMSG_RESET_START = 0x0, + WMTRSTMSG_RESET_END = 0x1, + 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 */ + ); + + +typedef enum _ENUM_WIFI_NETLINK_GRP_T{ + WIFI_NETLINK_GRP_RESET, + WIFI_NETLINK_GRP_MAX +} ENUM_WIFI_NETLINK_GRP_T, *P_ENUM_WIFI_NETLINK_GRP_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 +******************************************************************************** +*/ + +/*----------------------------------------------------------------------------*/ +/* Reset Initialization/Uninitialization */ +/*----------------------------------------------------------------------------*/ +VOID +glResetInit( + VOID + ); + +VOID +glResetUninit( + VOID + ); + +VOID +glSendResetRequest( + VOID + ); + +BOOLEAN +kalIsResetting( + VOID + ); + + +#endif /* _GL_RST_H */ diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_sec.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_sec.h new file mode 100755 index 000000000000..fe77d89ae78a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_sec.h @@ -0,0 +1,64 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2010 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + + +#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/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_typedef.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_typedef.h new file mode 100755 index 000000000000..31b6b0d2fc33 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_typedef.h @@ -0,0 +1,320 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_typedef.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + +#if defined(CONFIG_HAS_EARLYSUSPEND) +#include +#endif + +/******************************************************************************* +* C O M P I L E 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 (HZ) + +/* Miscellaneous Equates */ +#ifndef FALSE + #define FALSE ((BOOL) 0) + #define TRUE ((BOOL) 1) +#endif /* FALSE */ + +#ifndef NULL + #if defined(__cplusplus) + #define NULL 0 + #else + #define NULL ((void *) 0) + #endif +#endif + +#if defined(CONFIG_HAS_EARLYSUSPEND) +typedef void (*early_suspend_callback)(struct early_suspend *h); +typedef void (*late_resume_callback) (struct early_suspend *h); +#endif + + +/******************************************************************************* +* D A T A T Y P E S +******************************************************************************** +*/ +/* Type definition for void */ +typedef void VOID, *PVOID, **PPVOID; + +/* Type definition for Boolean */ +typedef unsigned char BOOL, *PBOOL, 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 long INT_32, *PINT_32, **PPINT_32; +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 long ULONG, UINT_32, *PUINT_32, **PPUINT_32; +typedef unsigned long long UINT_64, *PUINT_64, **PPUINT_64; + +typedef unsigned long OS_SYSTIME, *POS_SYSTIME, **PPOS_SYSTIME; + + +/* Type definition of large integer (64bits) union to be comptaible with + * Windows definition, so we won't apply our own coding style to these data types. + * NOTE: LARGE_INTEGER must NOT be floating variable. + * : Check for big-endian compatibility. + */ +typedef union _LARGE_INTEGER { + struct { + UINT_32 LowPart; + INT_32 HighPart; + } u; + INT_64 QuadPart; +} LARGE_INTEGER, *PLARGE_INTEGER; + +typedef union _ULARGE_INTEGER { + struct { + UINT_32 LowPart; + UINT_32 HighPart; + } u; + UINT_64 QuadPart; +} ULARGE_INTEGER, *PULARGE_INTEGER; + + +typedef INT_32 (*probe_card)(PVOID pvData); +typedef VOID (*remove_card)(VOID); + +/******************************************************************************* +* P U B 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_INLINE__ static __inline__ +#define __KAL_ATTRIB_PACKED__ __attribute__((__packed__)) +#define __KAL_ATTRIB_ALIGN_4__ __attribute__ ((aligned (4))) + + +#ifndef BIT +#define BIT(n) ((UINT_32) 1UL << (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) ((UINT_32)&(((_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) __constant_ntohs(_x) + + #define CONST_HTONS(_x) __constant_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/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext.h new file mode 100755 index 000000000000..138411a16b4a --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext.h @@ -0,0 +1,413 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/include/gl_wext.h#1 $ +*/ + +/*! \file gl_wext.h + \brief This file is for Portable Driver linux wireless extension support. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_wext.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 + ); + +int +wext_get_priv ( + IN struct net_device *prNetDev, + IN struct ifreq *prIfReq + ); + +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 + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* WIRELESS_EXT */ + +#endif /* _GL_WEXT_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext_priv.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext_priv.h new file mode 100755 index 000000000000..f49c30bfc235 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/include/gl_wext_priv.h @@ -0,0 +1,439 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/include/gl_wext_priv.h#1 $ +*/ + +/*! \file gl_wext_priv.h + \brief This file includes private ioctl support. +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: gl_wext_priv.h $ + * + * 01 20 2012 cp.wu + * [ALPS00096191] [MT6620 Wi-Fi][Driver][Firmware] Porting to ALPS4.0_DEV branch + * sync to up-to-date changes including: + * 1. BOW bugfix + * 2. XLOG + * + * 01 09 2012 wh.su + * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function + * Check in the Add Tx power Cmd to driver. + * + * 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 new priv CMD ID for P2P version set/query. + * + * 10 24 2011 terry.wu + * NULL + * Rollback to previous verson due to misbranch check-in + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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 +******************************************************************************** +*/ + +/******************************************************************************* +* 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 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 + +/* 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 + + +/* 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 + ); + +int +priv_support_ioctl ( + IN struct net_device *prDev, + IN OUT struct ifreq *prReq, + IN int i4Cmd + ); + +/******************************************************************************* +* F U N C T I O N S +******************************************************************************** +*/ + +#endif /* _GL_WEXT_PRIV_H */ + diff --git a/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/platform.c b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/platform.c new file mode 100755 index 000000000000..7ae1b9c78cf8 --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/linux/platform.c @@ -0,0 +1,694 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/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 + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $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. + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 09 13 2011 jeffrey.chang + * [WCXRP00000983] [MT6620][Wi-Fi Driver] invalid pointer casting causes kernel panic during p2p connection + * fix 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 09 2011 jeffrey.chang + * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change + * support ARP filter through kernel notifier + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 03 18 2011 jeffrey.chang + * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue + * remove early suspend functions + * + * 03 03 2011 jeffrey.chang + * NULL + * add the ARP filter callback + * + * 02 15 2011 jeffrey.chang + * NULL + * to support early suspend in android + * + * 02 01 2011 cp.wu + * [WCXRP00000413] [MT6620 Wi-Fi][Driver] Merge 1103 changes on NVRAM file path change to DaVinci main trunk and V1.1 branch + * upon Jason Zhang(NVRAM owner)'s change, ALPS has modified its NVRAM storage from /nvram/... to /data/nvram/... + * + * 11 01 2010 cp.wu + * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module + * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead + * 2) Remove CNM CH-RECOVER event handling + * 3) cfg read/write API renamed with kal prefix for unified naming rules. + * + * 10 18 2010 cp.wu + * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android + * complete implementation of Android NVRAM access + * + * 10 05 2010 cp.wu + * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check + * 1) add NVRAM access API + * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option) + * 3) add OID implementation for NVRAM read/write service + * +** +*/ +/******************************************************************************* +* C O M P I L E R F L A G S +******************************************************************************** +*/ + +/******************************************************************************* +* E X T E R N A L R E F E R E N C E S +******************************************************************************** +*/ +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12) + #include +#endif + +#include "gl_os.h" + +#ifndef CONFIG_X86 +#if defined(CONFIG_HAS_EARLY_SUSPEND) + #include +#endif +#endif + + +extern BOOLEAN fgIsUnderEarlierSuspend; + +/******************************************************************************* +* C O N S T A N T S +******************************************************************************** +*/ +#define WIFI_NVRAM_FILE_NAME "/data/nvram/APCFG/APRDEB/WIFI" +#define WIFI_NVRAM_CUSTOM_NAME "/data/nvram/APCFG/APRDEB/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, INFO, ("netdev_event: device is empty.\n")); + return NOTIFY_DONE; + } + + if ((strncmp(prDev->name, "p2p", 3) != 0) && (strncmp(prDev->name, "wlan", 4) != 0)) { + DBGLOG(REQ, INFO, ("netdev_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; + } + ASSERT(prGlueInfo); + + if (fgIsUnderEarlierSuspend == false) { + DBGLOG(REQ, INFO, ("netdev_event: PARAM_MEDIA_STATE_DISCONNECTED. (%d)\n", prGlueInfo->eParamMediaStateIndicated)); + return NOTIFY_DONE; + } + + + + // <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 avaliable.\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))){ + printk(KERN_INFO "ipv6 is not avaliable.\n"); + return NOTIFY_DONE; + } + + kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6)); + printk(KERN_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)((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)); + 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)((UINT_32)prParamNetAddr + sizeof(ip6)); + u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6); + } +#endif + ASSERT(u4Len <= sizeof(aucBuf)); + + DBGLOG(REQ, INFO, ("kalIoctl (0x%x, 0x%x)\n", prGlueInfo, prParamNetAddrList)); + + rStatus = kalIoctl(prGlueInfo, + wlanoidSetNetworkAddress, + (PVOID)prParamNetAddrList, + u4Len, + FALSE, + FALSE, + TRUE, + FALSE, + &u4SetInfoLen); + + if (rStatus != WLAN_STATUS_SUCCESS) { + DBGLOG(REQ, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus)); + } + } + + return NOTIFY_DONE; + +} + +static struct notifier_block inetaddr_notifier = { + .notifier_call = netdev_event, +}; + +void wlanRegisterNotifier(void) +{ + register_inetaddr_notifier(&inetaddr_notifier); +} + +EXPORT_SYMBOL(wlanRegisterNotifier); + +void wlanUnregisterNotifier(void) +{ + unregister_inetaddr_notifier(&inetaddr_notifier); +} + +EXPORT_SYMBOL(wlanUnregisterNotifier); + +#ifndef CONFIG_X86 +#if defined(CONFIG_HAS_EARLYSUSPEND) + + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will register platform driver to os +* +* \param[in] wlanSuspend Function pointer to platform suspend function +* \param[in] wlanResume Function pointer to platform resume function +* +* \return The result of registering earlysuspend +*/ +/*----------------------------------------------------------------------------*/ + +int glRegisterEarlySuspend( + struct early_suspend *prDesc, + early_suspend_callback wlanSuspend, + late_resume_callback wlanResume) +{ + int ret = 0; + + if(NULL != wlanSuspend) + prDesc->suspend = wlanSuspend; + else{ + DBGLOG(REQ, INFO, ("glRegisterEarlySuspend wlanSuspend ERROR.\n")); + ret = -1; + } + + if(NULL != wlanResume) + prDesc->resume = wlanResume; + else{ + DBGLOG(REQ, INFO, ("glRegisterEarlySuspend wlanResume ERROR.\n")); + ret = -1; + } + + register_early_suspend(prDesc); + return ret; +} + +EXPORT_SYMBOL(glRegisterEarlySuspend); + +/*----------------------------------------------------------------------------*/ +/*! +* \brief This function will un-register platform driver to os +* +* \return The result of un-registering earlysuspend +*/ +/*----------------------------------------------------------------------------*/ + +int glUnregisterEarlySuspend(struct early_suspend *prDesc) +{ + int ret = 0; + + unregister_early_suspend(prDesc); + + prDesc->suspend = NULL; + prDesc->resume = NULL; + + return ret; +} + +EXPORT_SYMBOL(glUnregisterEarlySuspend); +#endif +#endif // !CONFIG_X86 + +/*----------------------------------------------------------------------------*/ +/*! +* \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)) { + 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 = fd->f_op->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 = fd->f_op->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/mtk_wcn_combo/drv_wlan/wlan/os/version.h b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/version.h new file mode 100755 index 000000000000..a64c515c9bac --- /dev/null +++ b/drivers/mtk_wcn_combo/drv_wlan/wlan/os/version.h @@ -0,0 +1,197 @@ +/* +** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/version.h#1 $ +*/ + +/*! \file "version.h" + \brief Driver's version definition + +*/ + +/******************************************************************************* +* Copyright (c) 2007 MediaTek Inc. +* +* All rights reserved. Copying, compilation, modification, distribution +* or any other use whatsoever of this material is strictly prohibited +* except in accordance with a Software License Agreement with +* MediaTek Inc. +******************************************************************************** +*/ + +/******************************************************************************* +* LEGAL DISCLAIMER +* +* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND +* AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK +* SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE +* PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY +* DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT +* LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +* PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE +* ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY +* WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK +* SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY +* WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE +* FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO +* CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. +* +* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE +* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL +* BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT +* ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY +* BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +* +* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE +* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT +* OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING +* THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN +* FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE +* (ICC). +******************************************************************************** +*/ + +/* +** $Log: version.h $ + * + * 10 19 2011 yuche.tsai + * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch. + * Branch 2.1 + * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926. + * + * 03 18 2011 cp.wu + * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver + * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk + * + * 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(MT5931) + #define NIC_NAME "MT5931" + #define NIC_DEVICE_ID "MT5931" + #define NIC_DEVICE_ID_LOW "mt5931" + #elif defined(MT6628) + #define NIC_NAME "MT6628" + #define NIC_DEVICE_ID "MT6628" + #define NIC_DEVICE_ID_LOW "mt6628" + #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(MT5931) + #define NIC_PRODUCT_NAME "MediaTek Inc. MT5931 Wireless LAN Adapter" + #define NIC_DRIVER_NAME "MediaTek Inc. MT5931 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" +#endif + +/* Define our driver version */ +#define NIC_DRIVER_MAJOR_VERSION 2 +#define NIC_DRIVER_MINOR_VERSION 0 +#define NIC_DRIVER_VERSION 2,0,0,9 +#define NIC_DRIVER_VERSION_STRING "2.0.0.9" + + +/******************************************************************************* +* 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/mtk_wcn_combo/gps/Makefile b/drivers/mtk_wcn_combo/gps/Makefile new file mode 100755 index 000000000000..db3b2a544d88 --- /dev/null +++ b/drivers/mtk_wcn_combo/gps/Makefile @@ -0,0 +1,49 @@ +# Copyright Statement: +# +# This software/firmware and related documentation ("MediaTek Software") are +# protected under relevant copyright laws. The information contained herein +# is confidential and proprietary to MediaTek Inc. and/or its licensors. +# Without the prior written permission of MediaTek inc. and/or its licensors, +# any reproduction, modification, use or disclosure of MediaTek Software, +# and information contained herein, in whole or in part, shall be strictly prohibited. + +# MediaTek Inc. (C) 2010. All rights reserved. +# +# BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES +# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") +# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON +# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. +# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE +# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR +# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH +# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES +# THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES +# CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK +# SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR +# STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND +# CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, +# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, +# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO +# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. +# +# The following software/firmware and/or related documentation ("MediaTek Software") +# have been modified by MediaTek Inc. All revisions are subject to any receiver's +# applicable license agreements with MediaTek Inc. + + +# drivers/barcelona/gps/Makefile +# +# Makefile for the Barcelona GPS driver. +# +# Copyright (C) 2004,2005 TomTom BV +# Author: Dimitry Andric +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +obj-$(CONFIG_MTK_GPS) += gps.o + +# EOF diff --git a/drivers/mtk_wcn_combo/gps/gps.c b/drivers/mtk_wcn_combo/gps/gps.c new file mode 100755 index 000000000000..28bb7f4f012e --- /dev/null +++ b/drivers/mtk_wcn_combo/gps/gps.c @@ -0,0 +1,1117 @@ +/* Copyright Statement: + * + * This software/firmware and related documentation ("MediaTek Software") are + * protected under relevant copyright laws. The information contained herein + * is confidential and proprietary to MediaTek Inc. and/or its licensors. + * Without the prior written permission of MediaTek inc. and/or its licensors, + * any reproduction, modification, use or disclosure of MediaTek Software, + * and information contained herein, in whole or in part, shall be strictly prohibited. + */ +/* MediaTek Inc. (C) 2010. All rights reserved. + * + * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES + * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") + * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON + * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. + * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE + * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR + * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH + * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES + * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES + * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK + * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR + * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND + * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, + * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, + * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO + * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. + * + * The following software/firmware and/or related documentation ("MediaTek Software") + * have been modified by MediaTek Inc. All revisions are subject to any receiver's + * applicable license agreements with MediaTek Inc. + */ + +/* drivers/barcelona/gps/gps.c + * + * Implementation of the GPS driver. + * + * Copyright (C) 2004,2005 TomTom BV + * Authors: + * Jeroen Taverne + * Dimitry Andric + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/******************************************************************************* +* Dependency +*******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_ARCH_MT6573) +#include +#include +#elif defined(CONFIG_ARCH_MT6575) +#include +#include +#elif defined(CONFIG_ARCH_MT6516) +#include +#include +#include +#include +#endif + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +struct mt3326_gps_hardware{ + int (*ext_power_on)(int); + int (*ext_power_off)(int); +}; + +/****************************************************************************** + * Function Configuration +******************************************************************************/ +//#define FAKE_DATA +#define GPS_SUSPEND_RESUME +#define GPS_CONFIGURABLE_RESET_DELAY +/****************************************************************************** + * Definition +******************************************************************************/ +/* device name and major number */ +#define GPS_DEVNAME "mt3326-gps" +/****************************************************************************** + * Debug configuration +******************************************************************************/ +#define GPS_DBG_NONE(fmt, arg...) do {} while (0) +#define GPS_DBG_FUNC(fmt, arg...) printk(KERN_INFO PFX "%s: " fmt, __FUNCTION__ ,##arg) + +#define GPS_ERR(fmt, arg...) printk(KERN_ERR PFX "%s: " fmt, __FUNCTION__ ,##arg) +#define GPS_WARN(fmt, arg...) printk(KERN_WARNING PFX "%s: " fmt, __FUNCTION__ ,##arg) +#define GPS_NOTICE(fmt, arg...) printk(KERN_NOTICE PFX "%s: " fmt, __FUNCTION__ ,##arg) +#define GPS_INFO(fmt, arg...) printk(KERN_INFO PFX "%s: " fmt, __FUNCTION__ ,##arg) +#define GPS_TRC_FUNC(f) printk(PFX "<%s>\n", __FUNCTION__); +#define GPS_TRC_VERBOSE(fmt, arg...) printk(PFX fmt, ##arg) + +#define PFX "GPS: " +#define GPS_DBG GPS_DBG_FUNC +#define GPS_TRC GPS_DBG_NONE //GPS_TRC_FUNC +#define GPS_VER GPS_DBG_NONE //GPS_TRC_VERBOSE +#define IH_DBG GPS_DBG_NONE +/******************************************************************************* +* structure & enumeration +*******************************************************************************/ +enum { + GPS_PWRCTL_UNSUPPORTED = 0xFF, + GPS_PWRCTL_OFF = 0x00, + GPS_PWRCTL_ON = 0x01, + GPS_PWRCTL_RST = 0x02, + GPS_PWRCTL_OFF_FORCE = 0x03, + GPS_PWRCTL_RST_FORCE = 0x04, + GPS_PWRCTL_MAX = 0x05, +}; +enum { + GPS_PWR_UNSUPPORTED = 0xFF, + GPS_PWR_RESUME = 0x00, + GPS_PWR_SUSPEND = 0x01, + GPS_PWR_MAX = 0x02, +}; +enum { + GPS_STATE_UNSUPPORTED = 0xFF, + GPS_STATE_OFF = 0x00, /*cleanup/power off, default state*/ + GPS_STATE_INIT = 0x01, /*init*/ + GPS_STATE_START = 0x02, /*start navigating*/ + GPS_STATE_STOP = 0x03, /*stop navigating*/ + GPS_STATE_DEC_FREQ = 0x04, + GPS_STATE_SLEEP = 0x05, + GPS_STATE_MAX = 0x06, +}; +enum { + GPS_PWRSAVE_UNSUPPORTED = 0xFF, + GPS_PWRSAVE_DEC_FREQ = 0x00, + GPS_PWRSAVE_SLEEP = 0x01, + GPS_PWRSAVE_OFF = 0x02, + GPS_PWRSAVE_MAX = 0x03, +}; +/*---------------------------------------------------------------------------*/ +struct gps_data{ + int dat_len; + int dat_pos; + char dat_buf[4096]; + spinlock_t lock; + wait_queue_head_t read_wait; + struct semaphore sem; +}; +/*---------------------------------------------------------------------------*/ +struct gps_sta_itm { /*gps status record*/ + unsigned char year; /*current year - 1900*/ + unsigned char month; /*1~12*/ + unsigned char day; /*1~31*/ + unsigned char hour; /*0~23*/ + + unsigned char minute; /*0~59*/ + unsigned char sec; /*0~59*/ + unsigned char count; /*reborn count*/ + unsigned char reason; /*reason: 0: timeout; 1: force*/ +}; +/*---------------------------------------------------------------------------*/ +struct gps_sta_obj { + int index; + struct gps_sta_itm items[32]; +}; +/*---------------------------------------------------------------------------*/ +struct gps_drv_obj { + unsigned char pwrctl; + unsigned char suspend; + unsigned char state; + unsigned char pwrsave; + int rdelay; /*power reset delay*/ + struct kobject *kobj; + struct mutex sem; + struct gps_sta_obj status; + struct mt3326_gps_hardware *hw; +}; +/*---------------------------------------------------------------------------*/ +struct gps_dev_obj { + struct class *cls; + struct device *dev; + dev_t devno; + struct cdev chdev; + struct mt3326_gps_hardware *hw; +}; +/****************************************************************************** + * local variables +******************************************************************************/ +static struct gps_data gps_private= {0}; + +#if defined(FAKE_DATA) +static char fake_data[] = { +"$GPGGA,135036.000,2446.3713,N,12101.3605,E,1,5,1.61,191.1,M,15.1,M,,*51\r\n" +"$GPGSA,A,3,22,18,14,30,31,,,,,,,,1.88,1.61,0.98*09\r\n" +"$GPGSV,2,1,6,18,83,106,32,22,58,324,35,30,45,157,35,14,28,308,32*44\r\n" +"$GPGSV,2,2,6,40,21,254,,31,17,237,29*42\r\n" +"$GPRMC,135036.000,A,2446.37125,N,12101.36054,E,0.243,56.48,140109,,A*46\r\n" +"$GPVTG,56.48,T,,M,0.243,N,0.451,K,A*07\r\n" +}; +#endif //FAKE_DATA + +/*this should be synchronous with mnld.c +enum { + MNL_RESTART_NONE = 0x00, //recording the 1st of mnld + MNL_RESTART_TIMEOUT_INIT = 0x01, //restart due to timeout + MNL_RESTART_TIMEOUT_MONITOR = 0x02, //restart due to timeout + MNL_RESTART_TIMEOUT_WAKEUP = 0x03, //restart due to timeout + MNL_RESTART_TIMEOUT_TTFF = 0x04, //restart due to TTFF timeout + MNL_RESTART_FORCE = 0x04, //restart due to external command +}; +*/ +/*---------------------------------------------------------------------------*/ +static char *str_reason[] = {"none", "init", "monitor", "wakeup", "TTFF", "force", "unknown"}; +/****************************************************************************** + * Functions +******************************************************************************/ +static inline void mt3326_gps_power(struct mt3326_gps_hardware *hw, + unsigned int on, unsigned int force) +{ + /*FIX ME: PM_api should provide a function to get current status*/ + static unsigned int power_on = 1; + int err; + GPS_DBG("Switching GPS device %s\n", on ? "on" : "off"); + if (!hw) { + GPS_ERR("null pointer!!\n"); + return; + } + + if (power_on == on) { + GPS_DBG("ignore power control: %d\n", on); + } else if (on) { + /*power on*/ + if (hw->ext_power_on) { + err = hw->ext_power_on(0); + if (err) + GPS_ERR("ext_power_on fail\n"); + } +#if 0 +#ifndef MTK_MT6620 + if (!hwPowerOn(MT6516_POWER_V3GTX, VOL_2800,"MT3326")) { + GPS_ERR("power on fails!!\n"); + return; + } +#endif +#endif + if (hw->ext_power_on) { + err = hw->ext_power_on(1); + if (err) + GPS_ERR("ext_power_on fail\n"); + } + + #if 0 + if (!hwEnableClock(MT6516_PDN_PERI_UART2,"MT3326")) + GPS_ERR("enable clock fail"); + #endif + mdelay(120); + } else { + #if 0 + if (!hwDisableClock(MT6516_PDN_PERI_UART2,"MT3326")) + GPS_ERR("disable clock fail\n"); + #endif + if (hw->ext_power_off) { + err = hw->ext_power_off(force); + if (err) + GPS_ERR("ext_power_off fail\n"); + } +#if 0 +#ifndef MTK_MT6620 + if (force) { + /*TO FIX: the LDO pin is shared between modem + and external devices, it doesn't work if only + calling hwPowerDown*/ + typedef enum + { + V3GTX_ENABLE_WITH_SRCLKEN = 0, + V3GTX_ENABLE_WITH_V3GTX_EN + }v3gtx_on_sel_enum; + extern void pmic_v3gtx_on_sel(v3gtx_on_sel_enum); + pmic_v3gtx_on_sel(V3GTX_ENABLE_WITH_V3GTX_EN); + GPS_DBG("force power off!!\n"); + } + + if (!hwPowerDown(MT6516_POWER_V3GTX,"MT3326" )) + GPS_ERR("power off fail\n"); +#endif +#endif + } + power_on = on; +} +/*****************************************************************************/ +static inline void mt3326_gps_reset(struct mt3326_gps_hardware *hw, int delay, int force) +{ + mt3326_gps_power(hw, 1, FALSE); + mdelay(delay); + mt3326_gps_power(hw, 0, force); + mdelay(delay); + mt3326_gps_power(hw, 1, FALSE); +} +/******************************************************************************/ +static inline int mt3326_gps_set_suspend(struct gps_drv_obj* obj, + unsigned char suspend) +{ + if (!obj) + return -1; + mutex_lock(&obj->sem); + if (obj->suspend != suspend) { + GPS_DBG("issue sysfs_notify : %p\n", obj->kobj->sd); + sysfs_notify(obj->kobj, NULL, "suspend"); + } + obj->suspend = suspend; + mutex_unlock(&obj->sem); + return 0; +} +/******************************************************************************/ +static inline int mt3326_gps_set_pwrctl(struct gps_drv_obj* obj, + unsigned char pwrctl) +{ + int err = 0; + if (!obj) + return -1; + mutex_lock(&obj->sem); + + if ((pwrctl == GPS_PWRCTL_ON) || (pwrctl == GPS_PWRCTL_OFF)) { + obj->pwrctl = pwrctl; + mt3326_gps_power(obj->hw, pwrctl, FALSE); + } else if (pwrctl == GPS_PWRCTL_OFF_FORCE) { + obj->pwrctl = pwrctl; + mt3326_gps_power(obj->hw, pwrctl, TRUE); + } else if (pwrctl == GPS_PWRCTL_RST) { + mt3326_gps_reset(obj->hw, obj->rdelay, FALSE); + obj->pwrctl = GPS_PWRCTL_ON; + } else if (pwrctl == GPS_PWRCTL_RST_FORCE) { + mt3326_gps_reset(obj->hw, obj->rdelay, TRUE); + obj->pwrctl = GPS_PWRCTL_ON; + } else { + err = -1; + } + mutex_unlock(&obj->sem); + return err; +} + /******************************************************************************/ +static inline int mt3326_gps_set_status(struct gps_drv_obj* obj, + const char* buf, size_t count) +{ + int err = 0; + int year, mon, day, hour, minute, sec, cnt, reason, idx; + if (!obj) + return -1; + + mutex_lock(&obj->sem); + if (sscanf(buf, "(%d/%d/%d %d:%d:%d) - %d/%d", &year, &mon, &day, + &hour, &minute, &sec, &cnt, &reason) == 8) { + int number = (int)(sizeof(obj->status.items)/sizeof(obj->status.items[0])); + idx = obj->status.index % number; + obj->status.items[idx].year = (unsigned char)year; + obj->status.items[idx].month = (unsigned char)mon; + obj->status.items[idx].day = (unsigned char)day; + obj->status.items[idx].hour = (unsigned char)hour; + obj->status.items[idx].minute= (unsigned char)minute; + obj->status.items[idx].sec = (unsigned char)sec; + obj->status.items[idx].count = (unsigned char)cnt; + obj->status.items[idx].reason= (unsigned char)reason; + obj->status.index ++; + } else { + err = -1; + } + mutex_unlock(&obj->sem); + return err; +} +/******************************************************************************/ +static inline int mt3326_gps_set_state(struct gps_drv_obj* obj, + unsigned char state) +{ + int err = 0; + if (!obj) + return -1; + mutex_lock(&obj->sem); + if (state < GPS_STATE_MAX) + obj->state = state; + else + err = -1; + mutex_unlock(&obj->sem); + return err; +} +/******************************************************************************/ +static inline int mt3326_gps_set_pwrsave(struct gps_drv_obj* obj, + unsigned char pwrsave) +{ + int err = 0; + + if (!obj) + return -1; + mutex_lock(&obj->sem); + if (pwrsave < GPS_PWRSAVE_MAX) + obj->pwrsave = pwrsave; + else + err = -1; + mutex_unlock(&obj->sem); + return err; +} +/******************************************************************************/ +static inline int mt3326_gps_dev_suspend(struct gps_drv_obj *obj) +{ +#if defined(GPS_SUSPEND_RESUME) + int err; + + if ((err = mt3326_gps_set_suspend(obj, GPS_PWR_SUSPEND))) + GPS_DBG("set suspend fail: %d\n", err); + if ((err = mt3326_gps_set_pwrctl(obj, GPS_PWRCTL_OFF))) + GPS_DBG("set pwrctl fail: %d\n", err); + return err; +#endif +} +/******************************************************************************/ +static inline int mt3326_gps_dev_resume(struct gps_drv_obj *obj) +{ +#if defined(GPS_SUSPEND_RESUME) + int err; + + if ((err = mt3326_gps_set_suspend(obj, GPS_PWR_RESUME))) + GPS_DBG("set suspend fail: %d\n", err); + /*don't power on device automatically*/ + return err; +#endif +} +/******************************************************************************/ +static ssize_t mt3326_show_pwrctl(struct device* dev, + struct device_attribute *attr, char *buf) +{ + struct gps_drv_obj *obj; + ssize_t res; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + mutex_lock(&obj->sem); + res = snprintf(buf, PAGE_SIZE, "%d\n", obj->pwrctl); + mutex_unlock(&obj->sem); + return res; +} +/******************************************************************************/ +static ssize_t mt3326_store_pwrctl(struct device* dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + if ((count == 1) || + ((count == 2) && (buf[1] == '\n'))) { + unsigned char pwrctl = buf[0] - '0'; + if (!mt3326_gps_set_pwrctl(obj, pwrctl)) + return count; + } + GPS_DBG("invalid content: '%s', length = %d\n", buf, count); + return count; +} +/******************************************************************************/ +static ssize_t mt3326_show_suspend(struct device* dev, + struct device_attribute *attr, char *buf) +{ + struct gps_drv_obj *obj; + ssize_t res; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + mutex_lock(&obj->sem); + res = snprintf(buf, PAGE_SIZE, "%d\n", obj->suspend); + mutex_unlock(&obj->sem); + return res; +} +/******************************************************************************/ +static ssize_t mt3326_store_suspend(struct device* dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + if ((count == 1) || + ((count == 2) && (buf[1] == '\n'))) { + unsigned char suspend = buf[0] - '0'; + if (suspend == GPS_PWR_SUSPEND) { + if (!mt3326_gps_dev_suspend(obj)) + return count; + } else if (suspend == GPS_PWR_RESUME) { + if (!mt3326_gps_dev_resume(obj)) + return count; + } + } + GPS_DBG("invalid content: '%s', length = %d\n", buf, count); + return count; +} +/******************************************************************************/ +static ssize_t mt3326_show_status(struct device* dev, + struct device_attribute *attr, char *buf) +{ + int res, idx, num, left, cnt, len; + struct gps_drv_obj *obj; + char *reason = NULL; + int reason_max = (int)(sizeof(str_reason)/sizeof(str_reason[0])); + + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + mutex_lock(&obj->sem); + num = (int)(sizeof(obj->status.items)/sizeof(obj->status.items[0])); + left = PAGE_SIZE; + cnt = 0; + len = 0; + for (idx = 0; idx < num; idx++) { + if (obj->status.items[idx].month == 0) + continue; + if (obj->status.items[idx].reason >= reason_max) + reason = str_reason[reason_max-1]; + else + reason = str_reason[obj->status.items[idx].reason]; + cnt = snprintf(buf+len, left, "[%d] %.4d/%.2d/%.2d %.2d:%.2d:%.2d - %d, %s\n", idx, + obj->status.items[idx].year + 1900, obj->status.items[idx].month, + obj->status.items[idx].day, obj->status.items[idx].hour, + obj->status.items[idx].minute, obj->status.items[idx].sec, + obj->status.items[idx].count, reason); + left -= cnt; + len += cnt; + } + res = PAGE_SIZE - left; + mutex_unlock(&obj->sem); + return res; +} +/******************************************************************************/ +static ssize_t mt3326_store_status(struct device* dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + if (!mt3326_gps_set_status(obj, buf, count)) + return count; + GPS_DBG("invalid content: '%s', length = %d\n", buf, count); + return count; +} +/******************************************************************************/ +static ssize_t mt3326_show_state(struct device* dev, + struct device_attribute *attr, char *buf) +{ + ssize_t res; + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + mutex_lock(&obj->sem); + res = snprintf(buf, PAGE_SIZE, "%d\n", obj->state); + mutex_unlock(&obj->sem); + return res; +} +/******************************************************************************/ +static ssize_t mt3326_store_state(struct device* dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + if ((count == 1) || + ((count == 2) && (buf[1] == '\n'))) { /*To Do: dynamic change according to input*/ + unsigned char state = buf[0] - '0'; + if (!mt3326_gps_set_state(obj, state)) + return count; + } + GPS_DBG("invalid content: '%s', length = %d\n", buf, count); + return count; +} +/******************************************************************************/ +static ssize_t mt3326_show_pwrsave(struct device* dev, + struct device_attribute *attr, char *buf) +{ + ssize_t res; + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + mutex_lock(&obj->sem); + res = snprintf(buf, PAGE_SIZE, "%d\n", obj->pwrsave); + mutex_unlock(&obj->sem); + return res; +} +/******************************************************************************/ +static ssize_t mt3326_store_pwrsave(struct device* dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + if ((count == 1) || + ((count == 2) && (buf[1] == '\n'))) { + unsigned char pwrsave = buf[0] - '0'; + if (!mt3326_gps_set_pwrsave(obj, pwrsave)) + return count; + } + GPS_DBG("invalid content: '%s', length = %d\n", buf, count); + return count; +} +/******************************************************************************/ +#if defined(GPS_CONFIGURABLE_RESET_DELAY) +/******************************************************************************/ +static ssize_t mt3326_show_rdelay(struct device* dev, + struct device_attribute *attr, char *buf) +{ + ssize_t res; + struct gps_drv_obj *obj; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + mutex_lock(&obj->sem); + res = snprintf(buf, PAGE_SIZE, "%d\n", obj->rdelay); + mutex_unlock(&obj->sem); + return res; +} +/******************************************************************************/ +static ssize_t mt3326_store_rdelay(struct device* dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gps_drv_obj *obj; + int rdelay; + char *end; + if (!dev) { + GPS_DBG("dev is null!!\n"); + return 0; + } else if (!(obj = (struct gps_drv_obj*)dev_get_drvdata(dev))) { + GPS_DBG("drv data is null!!\n"); + return 0; + } + end = (char*)buf+count; + rdelay = (int)simple_strtol(buf, &end, 10); + if (rdelay < 2000) { + mutex_lock(&obj->sem); + obj->rdelay = rdelay; + mutex_unlock(&obj->sem); + return count; + } + GPS_DBG("invalid content: '%s', length = %d\n", buf, count); + return count; +} +/******************************************************************************/ +#endif +/******************************************************************************/ +DEVICE_ATTR(pwrctl, S_IWUSR | S_IWGRP | S_IRUGO, mt3326_show_pwrctl, mt3326_store_pwrctl); +DEVICE_ATTR(suspend, S_IWUSR | S_IWGRP | S_IRUGO, mt3326_show_suspend,mt3326_store_suspend); +DEVICE_ATTR(status, S_IWUSR | S_IWGRP | S_IRUGO, mt3326_show_status, mt3326_store_status); +DEVICE_ATTR(state, S_IWUSR | S_IWGRP | S_IRUGO, mt3326_show_state, mt3326_store_state); +DEVICE_ATTR(pwrsave, S_IWUSR | S_IWGRP | S_IRUGO, mt3326_show_pwrsave,mt3326_store_pwrsave); +#if defined(GPS_CONFIGURABLE_RESET_DELAY) +DEVICE_ATTR(rdelay, S_IWUSR | S_IWGRP | S_IRUGO, mt3326_show_rdelay ,mt3326_store_rdelay); +#endif +static struct device_attribute *gps_attr_list[] = { + &dev_attr_pwrctl, + &dev_attr_suspend, + &dev_attr_status, + &dev_attr_state, + &dev_attr_pwrsave, +#if defined(GPS_CONFIGURABLE_RESET_DELAY) + &dev_attr_rdelay, +#endif +}; +/******************************************************************************/ +static int mt3326_gps_create_attr(struct device *dev) +{ + int idx, err = 0; + int num = (int)(sizeof(gps_attr_list)/sizeof(gps_attr_list[0])); + if (!dev) + return -EINVAL; + + GPS_TRC(); + for (idx = 0; idx < num; idx++) { + if ((err = device_create_file(dev, gps_attr_list[idx]))) { + GPS_DBG("device_create_file (%s) = %d\n", gps_attr_list[idx]->attr.name, err); + break; + } + } + + return err; +} +/******************************************************************************/ +static int mt3326_gps_delete_attr(struct device *dev) +{ + int idx ,err = 0; + int num = (int)(sizeof(gps_attr_list)/sizeof(gps_attr_list[0])); + + if (!dev) + return -EINVAL; + + for (idx = 0; idx < num; idx++) + device_remove_file(dev, gps_attr_list[idx]); + + return err; +} +/******************************************************************************/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) +static int mt3326_gps_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} +#else +long mt3326_gps_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + GPS_DBG("mt3326_gps_unlocked_ioctl!!\n"); + return -ENOIOCTLCMD; +} +#endif +/*****************************************************************************/ +static int mt3326_gps_open(struct inode *inode, struct file *file) +{ + GPS_TRC(); + file->private_data = &gps_private; //all files share the same buffer + return nonseekable_open(inode, file); +} +/*****************************************************************************/ +static int mt3326_gps_release(struct inode *inode, struct file *file) +{ + struct gps_data *dev = file->private_data; + + GPS_TRC(); + + if (dev) + file->private_data = NULL; + + return 0; +} +/******************************************************************************/ +static ssize_t mt3326_gps_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + struct gps_data *dev = file->private_data; + ssize_t ret = 0; + int copy_len = 0; + + GPS_TRC(); + + if (!dev) + return -EINVAL; + + //printk("%s: %d\n", __FUNCTION__, dev->dat_len); + if (signal_pending(current)) + return -ERESTARTSYS; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + if (dev->dat_len == 0){ /*no data to be read*/ + up(&dev->sem); + if (file->f_flags & O_NONBLOCK) /*non-block mode*/ + return -EAGAIN; + do {/*block mode*/ + ret = wait_event_interruptible(dev->read_wait, (dev->dat_len > 0)); + if (ret == -ERESTARTSYS) + return -ERESTARTSYS; + }while(ret == 0); + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + } + + /*data is available*/ + copy_len = (dev->dat_len < (int)count) ? (dev->dat_len) : (int)(count); + if (copy_to_user(buf, dev->dat_buf+dev->dat_pos, (unsigned long)copy_len)){ + GPS_DBG("copy_to_user error: 0x%X 0x%X, %d\n", (unsigned int)buf, (unsigned int)dev->dat_buf, dev->dat_len); + ret = -EFAULT; + } else { + GPS_VER("mt3326_gps_read(%d,%d,%d) = %d\n", count, dev->dat_pos, dev->dat_len, copy_len); + if (dev->dat_len > (copy_len+dev->dat_pos)) { + dev->dat_pos += copy_len; + } else { + dev->dat_len = 0; + dev->dat_pos = 0; + } + ret = copy_len; + } + + up(&dev->sem); + GPS_VER("%s return %d bytes\n", __FUNCTION__, ret); + return ret; +} +/******************************************************************************/ +static ssize_t mt3326_gps_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ + struct gps_data *dev = file->private_data; + ssize_t ret = 0; + + GPS_TRC(); + + if (!dev) + return -EINVAL; + + if (!count) /*no data written*/ + return 0; + + if (signal_pending(current)) + return -ERESTARTSYS; + + if (down_interruptible(&dev->sem)) + return -ERESTARTSYS; + + if (copy_from_user(dev->dat_buf, buf, count)) { + GPS_DBG("copy_from_user error"); + ret = -EFAULT; + } else { + dev->dat_len = count; + dev->dat_pos = 0; + ret = count; + } + up(&dev->sem); + wake_up_interruptible(&dev->read_wait); + GPS_VER("%s: write %d bytes\n", __FUNCTION__, dev->dat_len); + return ret; +} +/******************************************************************************/ +static unsigned int mt3326_gps_poll(struct file *file, poll_table *wait) +{ + struct gps_data *dev = file->private_data; + unsigned int mask = 0; + + GPS_TRC(); + + if (!dev) + return 0; + + down(&dev->sem); + poll_wait(file, &dev->read_wait, wait); + if (dev->dat_len != 0) /*readable if data is available*/ + mask = (POLLIN|POLLRDNORM) | (POLLOUT|POLLWRNORM); + else /*always writable*/ + mask = (POLLOUT|POLLWRNORM); + up(&dev->sem); + GPS_VER("%s: mask : 0x%X\n", __FUNCTION__, mask); + return mask; +} +/*****************************************************************************/ +/* Kernel interface */ +static struct file_operations mt3326_gps_fops = { + .owner = THIS_MODULE, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) + .ioctl = mt3326_gps_ioctl, +#else + .unlocked_ioctl = mt3326_gps_unlocked_ioctl, +#endif + .open = mt3326_gps_open, + .read = mt3326_gps_read, + .write = mt3326_gps_write, + .release = mt3326_gps_release, + .poll = mt3326_gps_poll, +}; +/*****************************************************************************/ +extern unsigned int reset_state; +/*****************************************************************************/ +static void mt3326_gps_hw_init(struct mt3326_gps_hardware *hw) +{ + mt3326_gps_power(hw, 1, FALSE); +} +/*****************************************************************************/ +static void mt3326_gps_hw_exit(struct mt3326_gps_hardware *hw) +{ + mt3326_gps_power(hw, 0, FALSE); +} +/*****************************************************************************/ +static int mt3326_gps_probe(struct platform_device *dev) +{ + int ret = 0, err = 0; + struct gps_drv_obj *drvobj = NULL; + struct mt3326_gps_hardware *hw = (struct mt3326_gps_hardware*)dev->dev.platform_data; + struct gps_dev_obj *devobj = NULL; + + if (!(devobj = kzalloc(sizeof(*devobj), GFP_KERNEL))) + { + GPS_ERR("-ENOMEM\n"); + err = -ENOMEM; + goto error; + } + + mt3326_gps_hw_init(hw); + + GPS_DBG("Registering chardev\n"); + ret = alloc_chrdev_region(&devobj->devno, 0, 1, GPS_DEVNAME); + if (ret) { + GPS_ERR("alloc_chrdev_region fail: %d\n", ret); + goto error; + } else { + GPS_DBG("major: %d, minor: %d\n", MAJOR(devobj->devno), MINOR(devobj->devno)); + } + cdev_init(&devobj->chdev, &mt3326_gps_fops); + devobj->chdev.owner = THIS_MODULE; + err = cdev_add(&devobj->chdev, devobj->devno, 1); + if (err) { + GPS_ERR("cdev_add fail: %d\n", err); + goto error; + } + + if (!(drvobj = kmalloc(sizeof(*drvobj), GFP_KERNEL))) { + err = -ENOMEM; + goto error; + } + memset(drvobj, 0 ,sizeof(*drvobj)); + + devobj->cls = class_create(THIS_MODULE, "gpsdrv"); + if (IS_ERR(devobj->cls)) { + GPS_ERR("Unable to create class, err = %d\n", (int)PTR_ERR(devobj->cls)); + goto error; + } + devobj->dev = device_create(devobj->cls, NULL, devobj->devno, drvobj, "gps"); + drvobj->hw = hw; + drvobj->pwrctl = 0; + drvobj->suspend = 0; + drvobj->state = GPS_STATE_UNSUPPORTED; + drvobj->pwrsave = GPS_PWRSAVE_UNSUPPORTED; + drvobj->rdelay = 50; + drvobj->kobj = &devobj->dev->kobj; + mutex_init(&drvobj->sem); + + if ((err = mt3326_gps_create_attr(devobj->dev))) + goto error; + + /*initialize members*/ + spin_lock_init(&gps_private.lock); + init_waitqueue_head(&gps_private.read_wait); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) + init_MUTEX(&gps_private.sem); +#else + sema_init(&gps_private.sem, 1); +#endif + gps_private.dat_len = 0; + gps_private.dat_pos = 0; + memset(gps_private.dat_buf, 0x00, sizeof(gps_private.dat_buf)); + + /*set platform data: + a new device created for gps */ + platform_set_drvdata(dev, devobj); + + GPS_DBG("Done\n"); + return 0; + +error: + if (err == 0) + cdev_del(&devobj->chdev); + if (ret == 0) + unregister_chrdev_region(devobj->devno, 1); + return -1; +} +/*****************************************************************************/ +static int mt3326_gps_remove(struct platform_device *dev) +{ + struct gps_dev_obj *devobj = (struct gps_dev_obj*)platform_get_drvdata(dev); + struct gps_drv_obj *drvobj = (struct gps_drv_obj*)dev_get_drvdata(devobj->dev); + int err; + + if (!devobj || !drvobj) { + GPS_ERR("null pointer: %p, %p\n", devobj, drvobj); + return -1; + } + + GPS_DBG("Unregistering chardev\n"); + kfree(devobj); + + cdev_del(&devobj->chdev); + unregister_chrdev_region(devobj->devno, 1); + + mt3326_gps_hw_exit(devobj->hw); + if ((err = mt3326_gps_delete_attr(devobj->dev))) + GPS_ERR("delete attr fails: %d\n", err); + device_destroy(devobj->cls, devobj->devno); + class_destroy(devobj->cls); + GPS_DBG("Done\n"); + return 0; +} +/*****************************************************************************/ +static void mt3326_gps_shutdown(struct platform_device *dev) +{ + struct gps_dev_obj *devobj = (struct gps_dev_obj*)platform_get_drvdata(dev); + GPS_DBG("Shutting down\n"); + mt3326_gps_hw_exit(devobj->hw); +} +/*****************************************************************************/ +#ifdef CONFIG_PM +/*****************************************************************************/ +static int mt3326_gps_suspend(struct platform_device *dev, pm_message_t state) +{ + int err = 0; + struct gps_dev_obj *devobj = (struct gps_dev_obj*)platform_get_drvdata(dev); + struct gps_drv_obj *drvobj = (struct gps_drv_obj*)dev_get_drvdata(devobj->dev); + + if (!devobj || !drvobj) { + GPS_ERR("null pointer: %p, %p\n", devobj, drvobj); + return -1; + } + + GPS_DBG("dev = %p, event = %u,", dev, state.event); + if (state.event == PM_EVENT_SUSPEND) { + err = mt3326_gps_dev_suspend(drvobj); + } + return err; +} +/*****************************************************************************/ +static int mt3326_gps_resume(struct platform_device *dev) +{ + struct gps_dev_obj *devobj = (struct gps_dev_obj*)platform_get_drvdata(dev); + struct gps_drv_obj *drvobj = (struct gps_drv_obj*)dev_get_drvdata(devobj->dev); + + GPS_DBG(""); + return mt3326_gps_dev_resume(drvobj); +} +/*****************************************************************************/ +#endif /* CONFIG_PM */ +/*****************************************************************************/ +static struct platform_driver mt3326_gps_driver = +{ + .probe = mt3326_gps_probe, + .remove = mt3326_gps_remove, + .shutdown = mt3326_gps_shutdown, +#if defined(CONFIG_PM) + .suspend = mt3326_gps_suspend, + .resume = mt3326_gps_resume, +#endif + .driver = { + .name = GPS_DEVNAME, + .bus = &platform_bus_type, + }, +}; +/*****************************************************************************/ +static int __init mt3326_gps_mod_init(void) +{ + int ret = 0; + GPS_TRC(); + + //ret = driver_register(&mt3326_gps_driver); + ret = platform_driver_register(&mt3326_gps_driver); + + return ret; +} +/*****************************************************************************/ +static void __exit mt3326_gps_mod_exit(void) +{ + GPS_TRC(); + platform_driver_unregister(&mt3326_gps_driver); +} +/*****************************************************************************/ +module_init(mt3326_gps_mod_init); +module_exit(mt3326_gps_mod_exit); +/*****************************************************************************/ +MODULE_AUTHOR("MingHsien Hsieh "); +MODULE_DESCRIPTION("MT3326 GPS Driver"); +MODULE_LICENSE("GPL"); + + + diff --git a/include/linux/gps.h b/include/linux/gps.h new file mode 100755 index 000000000000..4a2a4a3e1e58 --- /dev/null +++ b/include/linux/gps.h @@ -0,0 +1,25 @@ + +#ifndef __GPS_H__ +#define __GPS_H__ + +//CC&C Johnson.Wang +//mtk gps device +static struct mt3326_gps_hardware { + int (*ext_power_on)(int); + int (*ext_power_off)(int); +}; + +static struct mt3326_gps_hardware mt3326_gps_hw = { + .ext_power_on = NULL, + .ext_power_off = NULL, +}; + +static struct platform_device mt3326_device_gps = { + .name = "mt3326-gps", + .id = -1, + .dev = { + .platform_data = &mt3326_gps_hw, + }, +}; + +#endif // __GPS_H__ -- 2.34.1